1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QT3DRENDER_RENDER_OPENGL_RENDERVIEW_H
6#define QT3DRENDER_RENDER_OPENGL_RENDERVIEW_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of other Qt classes. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <Qt3DRender/qparameter.h>
20#include <Qt3DRender/qclearbuffers.h>
21#include <Qt3DRender/qlayerfilter.h>
22#include <Qt3DRender/private/clearbuffers_p.h>
23#include <Qt3DRender/private/cameralens_p.h>
24#include <Qt3DRender/private/attachmentpack_p.h>
25#include <Qt3DRender/private/handle_types_p.h>
26#include <Qt3DRender/private/qsortpolicy_p.h>
27#include <Qt3DRender/private/lightsource_p.h>
28#include <Qt3DRender/private/qmemorybarrier_p.h>
29#include <Qt3DRender/private/qrendercapture_p.h>
30#include <Qt3DRender/private/qblitframebuffer_p.h>
31#include <Qt3DRender/private/waitfence_p.h>
32#include <Qt3DRender/private/renderercache_p.h>
33
34#include <Qt3DCore/private/aligned_malloc_p.h>
35
36#include <renderer_p.h>
37
38#include <QColor>
39#include <QList>
40#include <QMutex>
41#include <QSurface>
42
43QT_BEGIN_NAMESPACE
44
45namespace Qt3DRender {
46
47class QRenderPass;
48
49namespace Render {
50
51class NodeManagers;
52class RenderPassFilter;
53class TechniqueFilter;
54class ViewportNode;
55class Effect;
56class RenderPass;
57
58namespace OpenGL {
59
60class Renderer;
61class RenderCommand;
62
63typedef QPair<ShaderUniform, QVariant> ActivePropertyContent;
64typedef QPair<QString, ActivePropertyContent > ActiveProperty;
65
66using EntityRenderCommandData = Render::EntityRenderCommandData<RenderCommand>;
67using EntityRenderCommandDataView = Render::EntityRenderCommandDataView<RenderCommand>;
68using EntityRenderCommandDataViewPtr = Render::EntityRenderCommandDataViewPtr<RenderCommand>;
69using EntityRenderCommandDataSubView = Render::EntityRenderCommandDataSubView<RenderCommand>;
70
71struct Q_AUTOTEST_EXPORT ClearBufferInfo
72{
73 int drawBufferIndex = 0;
74 QRenderTargetOutput::AttachmentPoint attchmentPoint = QRenderTargetOutput::Color0;
75 QVector4D clearColor;
76};
77
78struct Q_AUTOTEST_EXPORT BlitFramebufferInfo
79{
80 Qt3DCore::QNodeId sourceRenderTargetId;
81 Qt3DCore::QNodeId destinationRenderTargetId;
82 QRect sourceRect;
83 QRect destinationRect;
84 Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint;
85 Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint;
86 QBlitFramebuffer::InterpolationMethod interpolationMethod;
87};
88
89// This class is kind of analogous to RenderBin but I want to avoid trampling
90// on that until we get this working
91
92class Q_AUTOTEST_EXPORT RenderView
93{
94public:
95 RenderView();
96 ~RenderView();
97
98 QT3D_ALIGNED_MALLOC_AND_FREE()
99
100 static void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv,
101 const FrameGraphNode *fgLeaf);
102
103 // TODO: Add a way to specify a sort predicate for the RenderCommands
104 void sort();
105
106 void setRenderer(Renderer *renderer);
107 inline void setSurfaceSize(const QSize &size) noexcept { m_surfaceSize = size; }
108 inline Renderer *renderer() const noexcept { return m_renderer; }
109 inline NodeManagers *nodeManagers() const noexcept { return m_manager; }
110 inline const QSize &surfaceSize() const noexcept { return m_surfaceSize; }
111 inline void setDevicePixelRatio(qreal r) noexcept { m_devicePixelRatio = r; }
112 inline qreal devicePixelRatio() const noexcept { return m_devicePixelRatio; }
113
114 inline void setRenderCameraLens(CameraLens *renderCameraLens) noexcept { m_renderCameraLens = renderCameraLens; }
115 inline CameraLens *renderCameraLens() const noexcept { return m_renderCameraLens; }
116
117 inline void setRenderCameraEntity(Entity *renderCameraNode) noexcept { m_renderCameraNode = renderCameraNode; }
118 inline Entity *renderCameraEntity() const noexcept { return m_renderCameraNode; }
119
120 inline void setViewMatrix(const Matrix4x4 &viewMatrix) noexcept { m_viewMatrix = viewMatrix; }
121 inline Matrix4x4 viewMatrix() const noexcept { return m_viewMatrix; }
122
123 inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) noexcept { m_viewProjectionMatrix = viewProjectionMatrix; }
124 inline Matrix4x4 viewProjectionMatrix() const noexcept { return m_viewProjectionMatrix; }
125
126 inline void setEyePosition(const Vector3D &eyePos) noexcept { m_eyePos = eyePos; }
127 inline Vector3D eyePosition() const noexcept { return m_eyePos; }
128
129 inline void setEyeViewDirection(const Vector3D &dir) noexcept { m_eyeViewDir = dir; }
130 inline Vector3D eyeViewDirection() const noexcept { return m_eyeViewDir; }
131
132 inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) noexcept { m_layerFilterIds.push_back(t: layerFilterId); }
133 inline Qt3DCore::QNodeIdVector layerFilters() const noexcept { return m_layerFilterIds; }
134
135 inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_proximityFilterIds.push_back(t: proximityFilterId); }
136 inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_proximityFilterIds; }
137
138 inline void appendInsertFenceId(const Qt3DCore::QNodeId setFenceId) { m_insertFenceIds.push_back(t: setFenceId); }
139 // We prefix with get to avoid confusion when it is called
140 inline Qt3DCore::QNodeIdVector insertFenceIds() const { return m_insertFenceIds; }
141
142 inline void appendWaitFence(const WaitFence::Data &data) { m_waitFences.push_back(t: data); }
143 inline QList<WaitFence::Data> waitFences() const { return m_waitFences; }
144
145 inline void setRenderPassFilter(const RenderPassFilter *rpFilter) noexcept { m_passFilter = rpFilter; }
146 inline const RenderPassFilter *renderPassFilter() const noexcept { return m_passFilter; }
147
148 inline void setTechniqueFilter(const TechniqueFilter *filter) noexcept { m_techniqueFilter = filter; }
149 inline const TechniqueFilter *techniqueFilter() const noexcept { return m_techniqueFilter; }
150
151 inline void setRenderCommandDataView(const EntityRenderCommandDataViewPtr &renderCommandDataView) noexcept { m_renderCommandDataView = renderCommandDataView; }
152 inline EntityRenderCommandDataViewPtr renderCommandDataView() const noexcept { return m_renderCommandDataView; }
153
154 RenderStateSet *getOrCreateStateSet();
155 RenderStateSet *stateSet() const noexcept { return m_stateSet.data(); }
156
157 inline bool noDraw() const noexcept { return m_noDraw; }
158 void setNoDraw(bool noDraw) noexcept { m_noDraw = noDraw; }
159
160 inline bool isCompute() const noexcept { return m_compute; }
161 void setCompute(bool compute) noexcept { m_compute = compute; }
162
163 void setComputeWorkgroups(int x, int y, int z) noexcept { m_workGroups[0] = x; m_workGroups[1] = y; m_workGroups[2] = z; }
164 const int *computeWorkGroups() const noexcept { return m_workGroups; }
165 inline bool frustumCulling() const noexcept { return m_frustumCulling; }
166 void setFrustumCulling(bool frustumCulling) noexcept { m_frustumCulling = frustumCulling; }
167 bool showDebugOverlay() const noexcept { return m_showDebugOverlay; }
168 void setShowDebugOverlay(bool showDebugOverlay) noexcept { m_showDebugOverlay = showDebugOverlay; }
169
170 inline void setMaterialParameterTable(const MaterialParameterGathererData &parameters) noexcept { m_parameters = parameters; }
171
172 // TODO: Get rid of this overly complex memory management by splitting out the
173 // InnerData as a RenderViewConfig struct. This can be created by setRenderViewConfigFromFrameGraphLeafNode
174 // and passed along with the RenderView to the functions that populate the renderview
175 inline void setViewport(const QRectF &vp) noexcept { m_viewport = vp; }
176 inline QRectF viewport() const noexcept { return m_viewport; }
177
178 inline float gamma() const noexcept { return m_gamma; }
179 inline void setGamma(float gamma) noexcept { m_gamma = gamma; }
180
181 // depth and stencil ClearBuffers are cached locally
182 // color ClearBuffers are collected, as there may be multiple
183 // color buffers to be cleared. we need to apply all these at rendering
184 void addClearBuffers(const ClearBuffers *cb);
185 inline const std::vector<ClearBufferInfo> &specificClearColorBufferInfo() const { return m_specificClearColorBuffers; }
186 inline std::vector<ClearBufferInfo> &specificClearColorBufferInfo() { return m_specificClearColorBuffers; }
187 inline ClearBufferInfo globalClearColorBufferInfo() const { return m_globalClearColorBuffer; }
188
189 inline QClearBuffers::BufferTypeFlags clearTypes() const { return m_clearBuffer; }
190 inline float clearDepthValue() const { return m_clearDepthValue; }
191 inline int clearStencilValue() const { return m_clearStencilValue; }
192
193 RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true);
194
195 EntityRenderCommandData buildDrawRenderCommands(const Entity **entities,
196 int offset, int count) const;
197 EntityRenderCommandData buildComputeRenderCommands(const Entity **entities,
198 int offset, int count) const;
199
200 void updateRenderCommand(const EntityRenderCommandDataSubView &subView);
201
202 void setAttachmentPack(const AttachmentPack &pack) { m_attachmentPack = pack; }
203 const AttachmentPack &attachmentPack() const { return m_attachmentPack; }
204
205 void setRenderTargetId(Qt3DCore::QNodeId renderTargetId) noexcept { m_renderTarget = renderTargetId; }
206 Qt3DCore::QNodeId renderTargetId() const noexcept { return m_renderTarget; }
207
208 void addSortType(const QList<Qt3DRender::QSortPolicy::SortType> &sortTypes) { m_sortingTypes.append(l: sortTypes); }
209
210 void setSurface(QSurface *surface) { m_surface = surface; }
211 QSurface *surface() const { return m_surface; }
212
213 void setLightSources(const std::vector<LightSource> &lightSources) noexcept { m_lightSources = lightSources; }
214 void setEnvironmentLight(EnvironmentLight *environmentLight) noexcept { m_environmentLight = environmentLight; }
215
216 void updateMatrices();
217
218 inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) noexcept { m_renderCaptureNodeId = nodeId; }
219 inline const Qt3DCore::QNodeId renderCaptureNodeId() const noexcept { return m_renderCaptureNodeId; }
220 inline void setRenderCaptureRequest(const QRenderCaptureRequest& request) noexcept { m_renderCaptureRequest = request; }
221 inline const QRenderCaptureRequest renderCaptureRequest() const noexcept { return m_renderCaptureRequest; }
222
223 void setMemoryBarrier(QMemoryBarrier::Operations barrier) noexcept { m_memoryBarrier = barrier; }
224 QMemoryBarrier::Operations memoryBarrier() const noexcept { return m_memoryBarrier; }
225
226 bool isDownloadBuffersEnable() const;
227 void setIsDownloadBuffersEnable(bool isDownloadBuffersEnable);
228
229 BlitFramebufferInfo blitFrameBufferInfo() const;
230 void setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo);
231
232 bool hasBlitFramebufferInfo() const;
233 void setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo);
234
235 bool shouldSkipSubmission() const;
236
237 template<typename F>
238 inline void forEachCommand(F func) const
239 {
240 if (!m_renderCommandDataView)
241 return;
242 m_renderCommandDataView->forEachCommand(func);
243 }
244
245 template<typename F>
246 inline void forEachCommand(F func)
247 {
248 if (!m_renderCommandDataView)
249 return;
250 m_renderCommandDataView->forEachCommand(func);
251 }
252
253 inline int commandCount() const { return m_renderCommandDataView ? int(m_renderCommandDataView->size()) : 0; }
254
255private:
256 void setShaderAndUniforms(RenderCommand *command,
257 const ParameterInfoList &parameters,
258 const Entity *entity) const;
259
260 void updateLightUniforms(RenderCommand *command,
261 const Entity *entity) const;
262
263 Renderer *m_renderer = nullptr;
264 NodeManagers *m_manager = nullptr;
265 EntityRenderCommandDataViewPtr m_renderCommandDataView;
266
267 QSize m_surfaceSize;
268 float m_devicePixelRatio = 1.0f;
269 QRectF m_viewport = QRectF(0.0f, 0.0f, 1.0f, 1.0f);
270 float m_gamma = 2.2f;
271
272 Qt3DCore::QNodeId m_renderCaptureNodeId;
273 QRenderCaptureRequest m_renderCaptureRequest;
274 bool m_isDownloadBuffersEnable = false;
275
276 bool m_hasBlitFramebufferInfo = false;
277 BlitFramebufferInfo m_blitFrameBufferInfo;
278
279 QSurface *m_surface = nullptr;
280 Qt3DCore::QNodeId m_renderTarget;
281 AttachmentPack m_attachmentPack;
282 QClearBuffers::BufferTypeFlags m_clearBuffer = QClearBuffers::None;
283 float m_clearDepthValue = 1.0f;
284 int m_clearStencilValue = 0;
285 ClearBufferInfo m_globalClearColorBuffer; // global ClearColor
286 std::vector<ClearBufferInfo> m_specificClearColorBuffers; // different draw buffers with distinct colors
287
288 QScopedPointer<RenderStateSet> m_stateSet;
289 CameraLens *m_renderCameraLens = nullptr;
290 Entity *m_renderCameraNode = nullptr;
291 const TechniqueFilter *m_techniqueFilter = nullptr;
292 const RenderPassFilter *m_passFilter = nullptr;
293 bool m_noDraw = false;
294 bool m_compute = false;
295 bool m_frustumCulling = false;
296 bool m_showDebugOverlay = false;
297 int m_workGroups[3] = { 1, 1, 1};
298 QMemoryBarrier::Operations m_memoryBarrier = QMemoryBarrier::None;
299 QList<Qt3DCore::QNodeId> m_insertFenceIds;
300 QList<WaitFence::Data> m_waitFences;
301 QList<Qt3DRender::QSortPolicy::SortType> m_sortingTypes;
302 Qt3DCore::QNodeIdVector m_proximityFilterIds;
303 Qt3DCore::QNodeIdVector m_layerFilterIds;
304 Matrix4x4 m_viewMatrix;
305 Matrix4x4 m_viewProjectionMatrix;
306 Vector3D m_eyePos;
307 Vector3D m_eyeViewDir;
308
309 MaterialParameterGathererData m_parameters;
310 mutable std::vector<LightSource> m_lightSources;
311 EnvironmentLight *m_environmentLight = nullptr;
312
313 enum StandardUniform
314 {
315 ModelMatrix,
316 ViewMatrix,
317 ProjectionMatrix,
318 ModelViewMatrix,
319 ViewProjectionMatrix,
320 ModelViewProjectionMatrix,
321 InverseModelMatrix,
322 InverseViewMatrix,
323 InverseProjectionMatrix,
324 InverseModelViewMatrix,
325 InverseViewProjectionMatrix,
326 InverseModelViewProjectionMatrix,
327 ModelNormalMatrix,
328 ModelViewNormalMatrix,
329 ViewportMatrix,
330 InverseViewportMatrix,
331 AspectRatio,
332 Time,
333 Exposure,
334 Gamma,
335 EyePosition,
336 SkinningPalette,
337 YUpInNDC,
338 YUpInFBO,
339 };
340
341 typedef QHash<int, StandardUniform> StandardUniformsNameToTypeHash;
342 static StandardUniformsNameToTypeHash ms_standardUniformSetters;
343 static StandardUniformsNameToTypeHash initializeStandardUniformSetters();
344
345 UniformValue standardUniformValue(StandardUniform standardUniformType,
346 const Entity *entity) const;
347
348 void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
349 void setStandardUniformValue(ShaderParameterPack &uniformPack,
350 int nameId,
351 const Entity *entity) const;
352 void setUniformBlockValue(ShaderParameterPack &uniformPack,
353 const ShaderUniformBlock &block,
354 const UniformValue &value) const;
355 void setShaderStorageValue(ShaderParameterPack &uniformPack,
356 const ShaderStorageBlock &block,
357 const UniformValue &value) const;
358 void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
359 const std::vector<int> &uniformsNamesIds,
360 ShaderData *shaderData,
361 const QString &structName) const;
362 void applyParameter(const Parameter *param,
363 RenderCommand *command,
364 const GLShader *shader) const noexcept;
365};
366
367} // namespace OpenGL
368} // namespace Render
369} // namespace Qt3DRender
370
371QT_END_NAMESPACE
372
373#endif // QT3DRENDER_RENDER_OPENGL_ENDERVIEW_H
374

source code of qt3d/src/plugins/renderers/opengl/renderer/renderview_p.h