1 | // Copyright (C) 2008-2012 NVIDIA Corporation. |
2 | // Copyright (C) 2022 The Qt Company Ltd. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
4 | |
5 | #ifndef QSSG_LAYER_RENDER_DATA_H |
6 | #define QSSG_LAYER_RENDER_DATA_H |
7 | |
8 | |
9 | // |
10 | // W A R N I N G |
11 | // ------------- |
12 | // |
13 | // This file is not part of the Qt API. It exists purely as an |
14 | // implementation detail. This header file may change from version to |
15 | // version without notice, or even be removed. |
16 | // |
17 | // We mean it. |
18 | // |
19 | |
20 | #include <QtQuick3DRuntimeRender/private/qssgrenderitem2d_p.h> |
21 | #include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h> |
22 | #include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h> |
23 | #include <QtQuick3DRuntimeRender/private/qssgrenderableobjects_p.h> |
24 | #include <QtQuick3DRuntimeRender/private/qssgrendershadowmap_p.h> |
25 | #include <QtQuick3DRuntimeRender/private/qssgrendereffect_p.h> |
26 | #include <QtQuick3DRuntimeRender/private/qssgrenderresourceloader_p.h> |
27 | #include <QtQuick3DRuntimeRender/private/qssgrenderreflectionmap_p.h> |
28 | #include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h> |
29 | #include <QtQuick3DRuntimeRender/private/qssgrhicontext_p.h> |
30 | #include <QtQuick3DRuntimeRender/private/qssgperframeallocator_p.h> |
31 | #include <QtQuick3DRuntimeRender/private/qssgshadermapkey_p.h> |
32 | #include <QtQuick3DRuntimeRender/private/qssglightmapper_p.h> |
33 | #include <ssg/qssgrenderextensions.h> |
34 | |
35 | #include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h> |
36 | |
37 | #include <optional> |
38 | #include <unordered_map> |
39 | |
40 | #include "qssgrenderpass_p.h" |
41 | |
42 | #define QSSG_RENDER_MINIMUM_RENDER_OPACITY .01f |
43 | |
44 | QT_BEGIN_NAMESPACE |
45 | |
46 | struct QSSGRenderableObject; |
47 | |
48 | enum class QSSGLayerRenderPreparationResultFlag |
49 | { |
50 | // Was the data in this layer dirty (meaning re-render to texture, possibly) |
51 | WasLayerDataDirty = 1 << 0, |
52 | |
53 | // Was the data in this layer dirty *or* this layer *or* any effect dirty. |
54 | WasDirty = 1 << 1, |
55 | |
56 | RequiresDepthTexture = 1 << 2, |
57 | |
58 | // SSAO should be done in a separate pass |
59 | // Note that having an AO pass necessitates a DepthTexture so this flag should |
60 | // never be set without the RequiresDepthTexture flag as well. |
61 | RequiresSsaoPass = 1 << 3, |
62 | |
63 | // if some light cause shadow |
64 | // we need a separate per light shadow map pass |
65 | RequiresShadowMapPass = 1 << 4, |
66 | |
67 | RequiresScreenTexture = 1 << 5, |
68 | |
69 | // set together with RequiresScreenTexture when SCREEN_MIP_TEXTURE is used |
70 | RequiresMipmapsForScreenTexture = 1 << 6 |
71 | }; |
72 | |
73 | struct QSSGLayerRenderPreparationResultFlags : public QFlags<QSSGLayerRenderPreparationResultFlag> |
74 | { |
75 | bool wasLayerDataDirty() const |
76 | { |
77 | return this->operator&(other: QSSGLayerRenderPreparationResultFlag::WasLayerDataDirty); |
78 | } |
79 | void setLayerDataDirty(bool inValue) |
80 | { |
81 | setFlag(flag: QSSGLayerRenderPreparationResultFlag::WasLayerDataDirty, on: inValue); |
82 | } |
83 | |
84 | bool wasDirty() const { return this->operator&(other: QSSGLayerRenderPreparationResultFlag::WasDirty); } |
85 | void setWasDirty(bool inValue) { setFlag(flag: QSSGLayerRenderPreparationResultFlag::WasDirty, on: inValue); } |
86 | |
87 | bool requiresDepthTexture() const |
88 | { |
89 | return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresDepthTexture); |
90 | } |
91 | void setRequiresDepthTexture(bool inValue) |
92 | { |
93 | setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresDepthTexture, on: inValue); |
94 | } |
95 | |
96 | bool requiresSsaoPass() const { return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresSsaoPass); } |
97 | void setRequiresSsaoPass(bool inValue) |
98 | { |
99 | setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresSsaoPass, on: inValue); |
100 | } |
101 | |
102 | bool requiresShadowMapPass() const |
103 | { |
104 | return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresShadowMapPass); |
105 | } |
106 | void setRequiresShadowMapPass(bool inValue) |
107 | { |
108 | setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresShadowMapPass, on: inValue); |
109 | } |
110 | |
111 | bool requiresScreenTexture() const |
112 | { |
113 | return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresScreenTexture); |
114 | } |
115 | void setRequiresScreenTexture(bool inValue) |
116 | { |
117 | setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresScreenTexture, on: inValue); |
118 | } |
119 | |
120 | bool requiresMipmapsForScreenTexture() const |
121 | { |
122 | return this->operator&(other: QSSGLayerRenderPreparationResultFlag::RequiresMipmapsForScreenTexture); |
123 | } |
124 | void setRequiresMipmapsForScreenTexture(bool inValue) |
125 | { |
126 | setFlag(flag: QSSGLayerRenderPreparationResultFlag::RequiresMipmapsForScreenTexture, on: inValue); |
127 | } |
128 | }; |
129 | |
130 | struct QSSGLayerRenderPreparationResult |
131 | { |
132 | QSSGLayerRenderPreparationResultFlags flags; |
133 | QRectF viewport; |
134 | QSSGRenderLayer *layer = nullptr; |
135 | |
136 | QSSGLayerRenderPreparationResult() = default; |
137 | QSSGLayerRenderPreparationResult(const QRectF &inViewport, QSSGRenderLayer &inLayer); |
138 | |
139 | bool isNull() const { return !layer; } |
140 | bool isLayerVisible() const; |
141 | QSize textureDimensions() const; |
142 | QSSGCameraGlobalCalculationResult setupCameraForRender(QSSGRenderCamera &inCamera, float dpr = 1.0f); |
143 | }; |
144 | |
145 | struct QSSGDefaultMaterialPreparationResult |
146 | { |
147 | QSSGRenderableImage *firstImage; |
148 | float opacity; |
149 | QSSGRenderableObjectFlags renderableFlags; |
150 | QSSGShaderDefaultMaterialKey materialKey; |
151 | bool dirty; |
152 | |
153 | explicit QSSGDefaultMaterialPreparationResult(QSSGShaderDefaultMaterialKey inMaterialKey); |
154 | }; |
155 | |
156 | struct QSSGBakedLightingModel |
157 | { |
158 | QSSGBakedLightingModel(const QSSGRenderModel *model, const QVector<QSSGRenderableObjectHandle> &renderables) |
159 | : model(model), |
160 | renderables(renderables) |
161 | { } |
162 | |
163 | const QSSGRenderModel *model; |
164 | QVector<QSSGRenderableObjectHandle> renderables; |
165 | }; |
166 | |
167 | class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGLayerRenderData |
168 | { |
169 | public: |
170 | enum Enum { |
171 | MAX_AA_LEVELS = 8, |
172 | MAX_TEMPORAL_AA_LEVELS = 2, |
173 | }; |
174 | |
175 | using RenderableFilter = std::function<bool(QSSGModelContext *)>; |
176 | |
177 | QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer); |
178 | ~QSSGLayerRenderData(); |
179 | |
180 | typedef QVector<QSSGModelContext *> TModelContextPtrList; |
181 | using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>; |
182 | using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>; |
183 | |
184 | QSSGShaderDefaultMaterialKey generateLightingKey(QSSGRenderDefaultMaterial::MaterialLighting inLightingType, |
185 | const QSSGShaderLightListView &lights, bool receivesShadows = true); |
186 | |
187 | void prepareImageForRender(QSSGRenderImage &inImage, |
188 | QSSGRenderableImage::Type inMapType, |
189 | QSSGRenderableImage *&ioFirstImage, |
190 | QSSGRenderableImage *&ioNextImage, |
191 | QSSGRenderableObjectFlags &ioFlags, |
192 | QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey, |
193 | quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial = nullptr); |
194 | |
195 | void setVertexInputPresence(const QSSGRenderableObjectFlags &renderableFlags, |
196 | QSSGShaderDefaultMaterialKey &key); |
197 | |
198 | static void prepareModelBoneTextures(const QSSGRenderContextInterface &contextInterface, |
199 | const RenderableNodeEntries &renderableModels); |
200 | |
201 | // Helper functions used during PrepareForRender and PrepareAndRender |
202 | // Updates lights with model receivesShadows. Do not pass globalLights. |
203 | bool prepareModelsForRender(QSSGRenderContextInterface &ctx, |
204 | const RenderableNodeEntries &renderableModels, |
205 | QSSGLayerRenderPreparationResultFlags &ioFlags, |
206 | const QSSGRenderCameraList &allCameras, |
207 | const QSSGRenderCameraDataList &allCameraData, |
208 | TModelContextPtrList &modelContexts, |
209 | QSSGRenderableObjectList &opaqueObjects, |
210 | QSSGRenderableObjectList &transparentObjects, |
211 | QSSGRenderableObjectList &screenTextureObjects, |
212 | float lodThreshold = 0.0f); |
213 | bool prepareParticlesForRender(const RenderableNodeEntries &renderableParticles, const QSSGRenderCameraData &cameraData); |
214 | bool prepareItem2DsForRender(const QSSGRenderContextInterface &ctxIfc, |
215 | const RenderableItem2DEntries &renderableItem2Ds); |
216 | |
217 | void prepareResourceLoaders(); |
218 | |
219 | void prepareForRender(); |
220 | // Helper function used during prepareForRender |
221 | void prepareReflectionProbesForRender(); |
222 | |
223 | static qsizetype frustumCulling(const QSSGClippingFrustum &clipFrustum, const QSSGRenderableObjectList &renderables, QSSGRenderableObjectList &visibleRenderables); |
224 | [[nodiscard]] static qsizetype frustumCullingInline(const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables); |
225 | |
226 | |
227 | // Per-frame cache of renderable objects post-sort (for the MAIN rendering camera, i.e., don't use these lists for rendering from a different camera). |
228 | const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0); |
229 | // If layer depth test is false, this may also contain opaque objects. |
230 | const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0); |
231 | const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(const QSSGRenderCamera &camera, size_t index = 0); |
232 | const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels(); |
233 | const RenderableItem2DEntries &getRenderableItem2Ds(); |
234 | const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(const QSSGRenderCamera &camera, size_t index = 0); |
235 | const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(const QSSGRenderCamera &camera, size_t index = 0); |
236 | |
237 | void resetForFrame(); |
238 | |
239 | void maybeBakeLightmap(); |
240 | |
241 | QSSGFrameData &getFrameData(); |
242 | |
243 | ShadowMapPass shadowMapPass; |
244 | ReflectionMapPass reflectionMapPass; |
245 | ZPrePassPass zPrePassPass; |
246 | SSAOMapPass ssaoMapPass; |
247 | DepthMapPass depthMapPass; |
248 | ScreenMapPass screenMapPass; |
249 | ScreenReflectionPass reflectionPass; |
250 | Item2DPass item2DPass; |
251 | SkyboxPass skyboxPass; |
252 | SkyboxCubeMapPass skyboxCubeMapPass; |
253 | static constexpr size_t USERPASSES = 2; // See QSSGRenderLayer::RenderExtensionMode::Count |
254 | UserPass userPasses[USERPASSES]; |
255 | OpaquePass opaquePass; |
256 | TransparentPass transparentPass; |
257 | InfiniteGridPass infiniteGridPass; |
258 | DebugDrawPass debugDrawPass; |
259 | |
260 | // Built-in passes |
261 | QVarLengthArray<QSSGRenderPass *, 16> activePasses; |
262 | |
263 | QSSGRenderLayer &layer; |
264 | QSSGRenderer *renderer = nullptr; |
265 | // List of nodes we can render, not all may be active. Found by doing a depth-first |
266 | // search through m_FirstChild if length is zero. |
267 | |
268 | // renderableNodes have all lights, but properties configured for specific node |
269 | RenderableNodeEntries renderableModels; |
270 | RenderableNodeEntries renderableParticles; |
271 | QVector<QSSGRenderItem2D *> renderableItem2Ds; |
272 | QVector<QSSGRenderCamera *> cameras; |
273 | QVector<QSSGRenderLight *> lights; |
274 | QVector<QSSGRenderReflectionProbe *> reflectionProbes; |
275 | |
276 | // Results of prepare for render. |
277 | QSSGRenderCameraList renderedCameras; // multiple items with multiview, one otherwise (or zero if no cameras at all) |
278 | QSSGShaderLightList globalLights; // All non-scoped lights |
279 | |
280 | QVector<QSSGBakedLightingModel> bakedLightingModels; |
281 | // Sorted lists of the rendered objects. There may be other transforms applied so |
282 | // it is simplest to duplicate the lists. |
283 | QVector<QSSGBakedLightingModel> renderedBakedLightingModels; |
284 | RenderableItem2DEntries renderedItem2Ds; |
285 | |
286 | QSSGLayerRenderPreparationResult layerPrepResult; |
287 | std::optional<QSSGRenderCameraDataList> renderedCameraData; |
288 | |
289 | TModelContextPtrList modelContexts; |
290 | |
291 | |
292 | bool tooManyLightsWarningShown = false; |
293 | bool tooManyShadowLightsWarningShown = false; |
294 | |
295 | QSSGLightmapper *m_lightmapper = nullptr; |
296 | |
297 | QSSGShaderFeatures getShaderFeatures() const { return features; } |
298 | QSSGRhiGraphicsPipelineState getPipelineState() const { return ps; } |
299 | |
300 | bool interactiveLightmapBakingRequested = false; |
301 | QSSGLightmapper::Callback lightmapBakingOutputCallback; |
302 | |
303 | [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id) const; |
304 | [[nodiscard]] QSSGRenderCamera *activeCamera() const { return !renderedCameras.isEmpty() ? renderedCameras[0] : nullptr; } |
305 | |
306 | [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera); |
307 | [[nodiscard]] QSSGRenderCameraData getCameraRenderData(const QSSGRenderCamera *camera) const; |
308 | |
309 | void setLightmapTexture(const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture); |
310 | [[nodiscard]] QRhiTexture *getLightmapTexture(const QSSGModelContext &modelContext) const; |
311 | |
312 | void setBonemapTexture(const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture); |
313 | [[nodiscard]] QRhiTexture *getBonemapTexture(const QSSGModelContext &modelContext) const; |
314 | |
315 | [[nodiscard]] QSSGRenderContextInterface *contextInterface() const; |
316 | // Note: temp. API to report the state of the z-prepass step |
317 | [[nodiscard]] bool isZPrePassActive() const { return zPrePassActive; } |
318 | void setZPrePassPrepResult(bool res) { zPrePassActive = res; } |
319 | |
320 | // Exposed as const, as we often need to use this to look-up values from a specific key. |
321 | [[nodiscard]] const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable() const |
322 | { |
323 | return defaultMaterialShaderKeyProperties; |
324 | } |
325 | |
326 | struct GlobalRenderProperties |
327 | { |
328 | bool isYUpInFramebuffer = true; |
329 | bool isYUpInNDC = true; |
330 | bool isClipDepthZeroToOne = true; |
331 | }; |
332 | |
333 | [[nodiscard]] static GlobalRenderProperties globalRenderProperties(const QSSGRenderContextInterface &ctx); |
334 | |
335 | // Temp. API. Ideally there shouldn't be a reason for anyone to hold onto these, |
336 | // but we follow the existing pattern for now. |
337 | const QSSGRenderShadowMapPtr &requestShadowMapManager(); |
338 | const QSSGRenderReflectionMapPtr &requestReflectionMapManager(); |
339 | const QSSGRenderShadowMapPtr &getShadowMapManager() const { return shadowMapManager; } |
340 | const QSSGRenderReflectionMapPtr &getReflectionMapManager() const { return reflectionMapManager; } |
341 | |
342 | static bool prepareInstancing(QSSGRhiContext *rhiCtx, |
343 | QSSGSubsetRenderable *renderable, |
344 | const QVector3D &cameraDirection, |
345 | const QVector3D &cameraPosition, |
346 | float minThreshold, |
347 | float maxThreshold); |
348 | |
349 | [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGFrameData::RenderResult id) { return &renderResults[size_t(id)]; } |
350 | [[nodiscard]] const QSSGRhiRenderableTexture *getRenderResult(QSSGFrameData::RenderResult id) const { return &renderResults[size_t(id)]; } |
351 | [[nodiscard]] static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx); |
352 | [[nodiscard]] static inline QSSGLayerRenderData *getCurrent(const QSSGRenderer &renderer) { return renderer.m_currentLayer; } |
353 | |
354 | static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode) |
355 | { |
356 | features.set(feature: QSSGShaderFeatures::Feature::LinearTonemapping, |
357 | val: tonemapMode == QSSGRenderLayer::TonemapMode::Linear); |
358 | features.set(feature: QSSGShaderFeatures::Feature::AcesTonemapping, |
359 | val: tonemapMode == QSSGRenderLayer::TonemapMode::Aces); |
360 | features.set(feature: QSSGShaderFeatures::Feature::HejlDawsonTonemapping, |
361 | val: tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson); |
362 | features.set(feature: QSSGShaderFeatures::Feature::FilmicTonemapping, |
363 | val: tonemapMode == QSSGRenderLayer::TonemapMode::Filmic); |
364 | features.set(feature: QSSGShaderFeatures::Feature::ForceIblExposure, |
365 | val: tonemapMode == QSSGRenderLayer::TonemapMode::Custom); |
366 | } |
367 | |
368 | QSSGPrepContextId getOrCreateExtensionContext(const QSSGRenderExtension &ext, |
369 | QSSGRenderCamera *camera = nullptr, |
370 | quint32 slot = 0); |
371 | |
372 | // Model API |
373 | QSSGRenderablesId createRenderables(QSSGPrepContextId prepId, const QList<QSSGNodeId> &nodes, QSSGRenderHelpers::CreateFlags createFlags); |
374 | void setGlobalTransform(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QMatrix4x4 &mvp); |
375 | QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId, const QSSGRenderModel &model); |
376 | void setGlobalOpacity(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, float opacity); |
377 | float getGlobalOpacity(QSSGPrepContextId prepId, const QSSGRenderModel &model); |
378 | [[nodiscard]] QMatrix4x4 getModelMvp(QSSGPrepContextId prepId, const QSSGRenderModel &model) const; |
379 | void setModelMaterials(QSSGRenderablesId renderablesId, const QSSGRenderModel &model, const QList<QSSGResourceId> &materials); |
380 | void setModelMaterials(const QSSGRenderablesId renderablesId, const QList<QSSGResourceId> &materials); |
381 | [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface, |
382 | QSSGPrepContextId prepId, |
383 | QSSGRenderablesId renderablesId, |
384 | float lodThreshold); |
385 | |
386 | |
387 | // |
388 | void prepareRenderables(QSSGRenderContextInterface &ctx, |
389 | QSSGPrepResultId prepId, |
390 | QRhiRenderPassDescriptor *renderPassDescriptor, |
391 | const QSSGRhiGraphicsPipelineState &ps, |
392 | QSSGRenderablesFilters filter); |
393 | void renderRenderables(QSSGRenderContextInterface &ctx, |
394 | QSSGPrepResultId prepId); |
395 | |
396 | private: |
397 | friend class QSSGRenderer; |
398 | friend class QSSGRendererPrivate; |
399 | friend class QSSGFrameData; |
400 | friend class QSSGModelHelpers; |
401 | friend class QSSGRenderHelpers; |
402 | |
403 | struct ExtensionContext |
404 | { |
405 | const QSSGRenderExtension *owner = nullptr; |
406 | QSSGRenderCamera *camera = nullptr; |
407 | QSSGRhiGraphicsPipelineState ps[3] {}; |
408 | QSSGRenderablesFilters filter { 0 }; |
409 | size_t index = 0; // index into the model store |
410 | quint32 slot = 0; |
411 | }; |
412 | |
413 | std::vector<ExtensionContext> extContexts { { /* 0 - Always available */ } }; |
414 | std::vector<RenderableNodeEntries> renderableModelStore { { /* 0 - Always available */ } }; |
415 | std::vector<TModelContextPtrList> modelContextStore { { /* 0 - Always available */ }}; |
416 | std::vector<QSSGRenderableObjectList> renderableObjectStore { { /* 0 - Always available */ }}; |
417 | std::vector<QSSGRenderableObjectList> opaqueObjectStore { { /* 0 - Always available */ }}; |
418 | std::vector<QSSGRenderableObjectList> transparentObjectStore { { /* 0 - Always available */ }}; |
419 | std::vector<QSSGRenderableObjectList> screenTextureObjectStore { { /* 0 - Always available */ }}; |
420 | |
421 | // Soreted cache (per camera and extension) |
422 | using PerCameraCache = std::unordered_map<const QSSGRenderCamera *, QSSGRenderableObjectList>; |
423 | std::vector<PerCameraCache> sortedOpaqueObjectCache { { /* 0 - Always available */ } }; |
424 | std::vector<PerCameraCache> sortedTransparentObjectCache { { /* 0 - Always available */ } }; |
425 | std::vector<PerCameraCache> sortedScreenTextureObjectCache { { /* 0 - Always available */ } }; |
426 | std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { { /* 0 - Always available */ } }; |
427 | std::vector<PerCameraCache> sortedDepthWriteCache { { /* 0 - Always available */ } }; |
428 | |
429 | [[nodiscard]] const QSSGRenderCameraDataList &getCachedCameraDatas(); |
430 | void ensureCachedCameraDatas(); |
431 | void updateSortedDepthObjectsListImp(const QSSGRenderCamera &camera, size_t index); |
432 | |
433 | |
434 | QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial, |
435 | QSSGRenderableObjectFlags &inExistingFlags, |
436 | float inOpacity, |
437 | const QSSGShaderLightListView &lights, |
438 | QSSGLayerRenderPreparationResultFlags &ioFlags); |
439 | |
440 | QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial, |
441 | QSSGRenderableObjectFlags &inExistingFlags, |
442 | float inOpacity, bool alreadyDirty, |
443 | const QSSGShaderLightListView &lights, |
444 | QSSGLayerRenderPreparationResultFlags &ioFlags); |
445 | |
446 | static void prepareModelMaterials(RenderableNodeEntries &renderableModels, bool cullUnrenderables); |
447 | static void prepareModelMaterials(const RenderableNodeEntries::ConstIterator &begin, |
448 | const RenderableNodeEntries::ConstIterator &end); |
449 | // Load meshes as needed |
450 | static void prepareModelMeshes(const QSSGRenderContextInterface &contextInterface, |
451 | RenderableNodeEntries &renderableModels, |
452 | bool globalPickingEnabled); |
453 | static void prepareModelMeshes(const QSSGRenderContextInterface &contextInterface, |
454 | const RenderableNodeEntries::ConstIterator begin, |
455 | const RenderableNodeEntries::ConstIterator end, |
456 | bool globalPickingEnabled); |
457 | |
458 | // Persistent data |
459 | QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap; |
460 | |
461 | // Note: Re-used to avoid expensive initialization. |
462 | // - Should be revisit, as we can do better. |
463 | QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties; |
464 | QSSGFrameData frameData; |
465 | QSSGRhiGraphicsPipelineState ps; // Base pipleline state |
466 | QSSGShaderFeatures features; // Base feature set |
467 | bool particlesEnabled = true; |
468 | bool hasDepthWriteObjects = false; |
469 | bool zPrePassActive = false; |
470 | enum class DepthPrepassObject : quint8 |
471 | { |
472 | None = 0x0, |
473 | ScreenTexture = 0x1, |
474 | Transparent = 0x2, |
475 | Opaque = 0x4 |
476 | }; |
477 | using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>; |
478 | DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) }; |
479 | QSSGRenderShadowMapPtr shadowMapManager; |
480 | QSSGRenderReflectionMapPtr reflectionMapManager; |
481 | QHash<const QSSGModelContext *, QRhiTexture *> lightmapTextures; |
482 | QHash<const QSSGModelContext *, QRhiTexture *> bonemapTextures; |
483 | QSSGRhiRenderableTexture renderResults[3] {}; |
484 | }; |
485 | |
486 | QT_END_NAMESPACE |
487 | |
488 | #endif // QSSG_LAYER_RENDER_DATA_H |
489 | |
490 | |