1/****************************************************************************
2**
3** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the Qt3D module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#ifndef QT3DRENDER_RENDER_RENDERVIEW_H
42#define QT3DRENDER_RENDER_RENDERVIEW_H
43
44//
45// W A R N I N G
46// -------------
47//
48// This file is not part of the Qt API. It exists for the convenience
49// of other Qt classes. This header file may change from version to
50// version without notice, or even be removed.
51//
52// We mean it.
53//
54
55#include <Qt3DRender/qparameter.h>
56#include <Qt3DRender/qclearbuffers.h>
57#include <Qt3DRender/qlayerfilter.h>
58#include <Qt3DRender/private/renderer_p.h>
59#include <Qt3DRender/private/clearbuffers_p.h>
60#include <Qt3DRender/private/cameralens_p.h>
61#include <Qt3DRender/private/attachmentpack_p.h>
62#include <Qt3DRender/private/handle_types_p.h>
63#include <Qt3DRender/private/qsortpolicy_p.h>
64#include <Qt3DRender/private/lightsource_p.h>
65#include <Qt3DRender/private/qmemorybarrier_p.h>
66#include <Qt3DRender/private/qrendercapture_p.h>
67#include <Qt3DRender/private/qblitframebuffer_p.h>
68#include <Qt3DRender/private/qwaitfence_p.h>
69
70#include <Qt3DCore/private/qframeallocator_p.h>
71#include <Qt3DRender/private/aligned_malloc_p.h>
72
73// TODO: Move out once this is all refactored
74#include <Qt3DRender/private/renderviewjobutils_p.h>
75
76#include <QVector>
77#include <QSurface>
78#include <QMutex>
79#include <QColor>
80
81QT_BEGIN_NAMESPACE
82
83namespace Qt3DRender {
84
85class QRenderPass;
86
87namespace Render {
88
89class Renderer;
90class NodeManagers;
91class RenderCommand;
92class RenderPassFilter;
93class TechniqueFilter;
94class ViewportNode;
95class Effect;
96class RenderPass;
97
98typedef QPair<ShaderUniform, QVariant> ActivePropertyContent;
99typedef QPair<QString, ActivePropertyContent > ActiveProperty;
100
101struct Q_AUTOTEST_EXPORT Plane
102{
103 explicit Plane(const Vector4D &planeEquation)
104 : planeEquation(planeEquation)
105 , normal(Vector3D(planeEquation).normalized())
106 , d(planeEquation.w() / Vector3D(planeEquation).length())
107 {}
108
109 const Vector4D planeEquation;
110 const Vector3D normal;
111 const float d;
112};
113
114struct Q_AUTOTEST_EXPORT ClearBufferInfo
115{
116 int drawBufferIndex = 0;
117 QRenderTargetOutput::AttachmentPoint attchmentPoint = QRenderTargetOutput::Color0;
118 QVector4D clearColor;
119};
120
121struct Q_AUTOTEST_EXPORT BlitFramebufferInfo
122{
123 Qt3DCore::QNodeId sourceRenderTargetId;
124 Qt3DCore::QNodeId destinationRenderTargetId;
125 QRect sourceRect;
126 QRect destinationRect;
127 Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint;
128 Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint;
129 QBlitFramebuffer::InterpolationMethod interpolationMethod;
130};
131
132// This class is kind of analogous to RenderBin but I want to avoid trampling
133// on that until we get this working
134
135class Q_AUTOTEST_EXPORT RenderView
136{
137public:
138 RenderView();
139 ~RenderView();
140
141 QT3D_ALIGNED_MALLOC_AND_FREE()
142
143 // TODO: Add a way to specify a sort predicate for the RenderCommands
144 void sort();
145
146 void setRenderer(Renderer *renderer);
147 inline void setSurfaceSize(const QSize &size) Q_DECL_NOTHROW { m_surfaceSize = size; }
148 inline Renderer *renderer() const Q_DECL_NOTHROW { return m_renderer; }
149 inline NodeManagers *nodeManagers() const Q_DECL_NOTHROW { return m_manager; }
150 inline const QSize &surfaceSize() const Q_DECL_NOTHROW { return m_surfaceSize; }
151 inline void setDevicePixelRatio(qreal r) Q_DECL_NOTHROW { m_devicePixelRatio = r; }
152 inline qreal devicePixelRatio() const Q_DECL_NOTHROW { return m_devicePixelRatio; }
153
154 inline void setRenderCameraLens(CameraLens *renderCameraLens) Q_DECL_NOTHROW { m_data.m_renderCameraLens = renderCameraLens; }
155 inline CameraLens *renderCameraLens() const Q_DECL_NOTHROW { return m_data.m_renderCameraLens; }
156
157 inline void setRenderCameraEntity(Entity *renderCameraNode) Q_DECL_NOTHROW { m_data.m_renderCameraNode = renderCameraNode; }
158 inline Entity *renderCameraEntity() const Q_DECL_NOTHROW { return m_data.m_renderCameraNode; }
159
160 inline void setViewMatrix(const Matrix4x4 &viewMatrix) Q_DECL_NOTHROW { m_data.m_viewMatrix = viewMatrix; }
161 inline Matrix4x4 viewMatrix() const Q_DECL_NOTHROW { return m_data.m_viewMatrix; }
162
163 inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW { m_data.m_viewProjectionMatrix = viewProjectionMatrix; }
164 inline Matrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW { return m_data.m_viewProjectionMatrix; }
165
166 inline void setEyePosition(const Vector3D &eyePos) Q_DECL_NOTHROW { m_data.m_eyePos = eyePos; }
167 inline Vector3D eyePosition() const Q_DECL_NOTHROW { return m_data.m_eyePos; }
168
169 inline void setEyeViewDirection(const Vector3D &dir) Q_DECL_NOTHROW { m_data.m_eyeViewDir = dir; }
170 inline Vector3D eyeViewDirection() const Q_DECL_NOTHROW { return m_data.m_eyeViewDir; }
171
172 inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_data.m_layerFilterIds.push_back(layerFilterId); }
173 inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_data.m_layerFilterIds; }
174
175 inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_data.m_proximityFilterIds.push_back(proximityFilterId); }
176 inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_data.m_proximityFilterIds; }
177
178 inline void appendInsertFenceId(const Qt3DCore::QNodeId setFenceId) { m_insertFenceIds.push_back(setFenceId); }
179 // We prefix with get to avoid confusion when it is called
180 inline Qt3DCore::QNodeIdVector insertFenceIds() const { return m_insertFenceIds; }
181
182 inline void appendWaitFence(const QWaitFenceData &data) { m_waitFences.push_back(data); }
183 inline QVector<QWaitFenceData> waitFences() const { return m_waitFences; }
184
185 inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_data.m_passFilter = rpFilter; }
186 inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_data.m_passFilter; }
187
188 inline void setTechniqueFilter(const TechniqueFilter *filter) Q_DECL_NOTHROW { m_data.m_techniqueFilter = filter; }
189 inline const TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW { return m_data.m_techniqueFilter; }
190
191 inline RenderStateSet *stateSet() const Q_DECL_NOTHROW { return m_stateSet; }
192 void setStateSet(RenderStateSet *stateSet) Q_DECL_NOTHROW { m_stateSet = stateSet; }
193
194 inline bool noDraw() const Q_DECL_NOTHROW { return m_noDraw; }
195 void setNoDraw(bool noDraw) Q_DECL_NOTHROW { m_noDraw = noDraw; }
196
197 inline bool isCompute() const Q_DECL_NOTHROW { return m_compute; }
198 void setCompute(bool compute) Q_DECL_NOTHROW { m_compute = compute; }
199
200 void setComputeWorkgroups(int x, int y, int z) Q_DECL_NOTHROW { m_workGroups[0] = x; m_workGroups[1] = y; m_workGroups[2] = z; }
201 const int *computeWorkGroups() const Q_DECL_NOTHROW { return m_workGroups; }
202 inline bool frustumCulling() const Q_DECL_NOTHROW { return m_frustumCulling; }
203 void setFrustumCulling(bool frustumCulling) Q_DECL_NOTHROW { m_frustumCulling = frustumCulling; }
204
205 inline void setMaterialParameterTable(const MaterialParameterGathererData &parameters) Q_DECL_NOTHROW { m_parameters = parameters; }
206
207 // TODO: Get rid of this overly complex memory management by splitting out the
208 // InnerData as a RenderViewConfig struct. This can be created by setRenderViewConfigFromFrameGraphLeafNode
209 // and passed along with the RenderView to the functions that populate the renderview
210 inline void setViewport(const QRectF &vp) Q_DECL_NOTHROW { m_viewport = vp; }
211 inline QRectF viewport() const Q_DECL_NOTHROW { return m_viewport; }
212
213 inline float gamma() const Q_DECL_NOTHROW { return m_gamma; }
214 inline void setGamma(float gamma) Q_DECL_NOTHROW { m_gamma = gamma; }
215
216 // depth and stencil ClearBuffers are cached locally
217 // color ClearBuffers are collected, as there may be multiple
218 // color buffers to be cleared. we need to apply all these at rendering
219 void addClearBuffers(const ClearBuffers *cb);
220 inline QVector<ClearBufferInfo> specificClearColorBufferInfo() const { return m_specificClearColorBuffers; }
221 inline QVector<ClearBufferInfo> &specificClearColorBufferInfo() { return m_specificClearColorBuffers; }
222 inline ClearBufferInfo globalClearColorBufferInfo() const { return m_globalClearColorBuffer; }
223
224 inline QClearBuffers::BufferTypeFlags clearTypes() const { return m_clearBuffer; }
225 inline float clearDepthValue() const { return m_clearDepthValue; }
226 inline int clearStencilValue() const { return m_clearStencilValue; }
227
228 RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true);
229
230 QVector<RenderCommand *> buildDrawRenderCommands(const QVector<Entity *> &entities) const;
231 QVector<RenderCommand *> buildComputeRenderCommands(const QVector<Entity *> &entities) const;
232 void setCommands(QVector<RenderCommand *> &commands) Q_DECL_NOTHROW { m_commands = commands; }
233 QVector<RenderCommand *> commands() const Q_DECL_NOTHROW { return m_commands; }
234
235 void setAttachmentPack(const AttachmentPack &pack) { m_attachmentPack = pack; }
236 const AttachmentPack &attachmentPack() const { return m_attachmentPack; }
237
238 void setRenderTargetId(Qt3DCore::QNodeId renderTargetId) Q_DECL_NOTHROW { m_renderTarget = renderTargetId; }
239 Qt3DCore::QNodeId renderTargetId() const Q_DECL_NOTHROW { return m_renderTarget; }
240
241 void addSortType(const QVector<Qt3DRender::QSortPolicy::SortType> &sortTypes) { m_data.m_sortingTypes.append(sortTypes); }
242
243 void setSurface(QSurface *surface) { m_surface = surface; }
244 QSurface *surface() const { return m_surface; }
245
246 void setLightSources(const QVector<LightSource> &lightSources) Q_DECL_NOTHROW { m_lightSources = lightSources; }
247 void setEnvironmentLight(EnvironmentLight *environmentLight) Q_DECL_NOTHROW { m_environmentLight = environmentLight; }
248
249 void updateMatrices();
250
251 inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) Q_DECL_NOTHROW { m_renderCaptureNodeId = nodeId; }
252 inline const Qt3DCore::QNodeId renderCaptureNodeId() const Q_DECL_NOTHROW { return m_renderCaptureNodeId; }
253 inline void setRenderCaptureRequest(const QRenderCaptureRequest& request) Q_DECL_NOTHROW { m_renderCaptureRequest = request; }
254 inline const QRenderCaptureRequest renderCaptureRequest() const Q_DECL_NOTHROW { return m_renderCaptureRequest; }
255
256 void setMemoryBarrier(QMemoryBarrier::Operations barrier) Q_DECL_NOTHROW { m_memoryBarrier = barrier; }
257 QMemoryBarrier::Operations memoryBarrier() const Q_DECL_NOTHROW { return m_memoryBarrier; }
258
259 // Helps making the size of RenderView smaller
260 // Contains all the data needed for the actual building of the RenderView
261 // But that aren't used later by the Renderer
262 struct InnerData {
263 InnerData()
264 : m_renderCameraLens(nullptr)
265 , m_renderCameraNode(nullptr)
266 , m_techniqueFilter(nullptr)
267 , m_passFilter(nullptr)
268 {
269 }
270 CameraLens *m_renderCameraLens;
271 Entity *m_renderCameraNode;
272 const TechniqueFilter *m_techniqueFilter;
273 const RenderPassFilter *m_passFilter;
274 Matrix4x4 m_viewMatrix;
275 Matrix4x4 m_viewProjectionMatrix;
276 Qt3DCore::QNodeIdVector m_layerFilterIds;
277 QVector<Qt3DRender::QSortPolicy::SortType> m_sortingTypes;
278 Vector3D m_eyePos;
279 Vector3D m_eyeViewDir;
280 Qt3DCore::QNodeIdVector m_proximityFilterIds;
281 };
282
283 bool isDownloadBuffersEnable() const;
284 void setIsDownloadBuffersEnable(bool isDownloadBuffersEnable);
285
286 BlitFramebufferInfo blitFrameBufferInfo() const;
287 void setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo);
288
289 bool hasBlitFramebufferInfo() const;
290 void setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo);
291
292private:
293 void setShaderAndUniforms(RenderCommand *command,
294 RenderPass *pass,
295 ParameterInfoList &parameters,
296 Entity *entity,
297 const QVector<LightSource> &activeLightSources,
298 EnvironmentLight *environmentLight) const;
299 mutable QThreadStorage<UniformBlockValueBuilder*> m_localData;
300
301 Qt3DCore::QNodeId m_renderCaptureNodeId;
302 QRenderCaptureRequest m_renderCaptureRequest;
303 bool m_isDownloadBuffersEnable;
304
305 bool m_hasBlitFramebufferInfo;
306 BlitFramebufferInfo m_blitFrameBufferInfo;
307
308 Renderer *m_renderer;
309 NodeManagers *m_manager;
310 QSize m_surfaceSize;
311 qreal m_devicePixelRatio;
312
313 InnerData m_data;
314
315 QRectF m_viewport;
316 float m_gamma;
317 Qt3DCore::QNodeId m_renderTarget;
318 QSurface *m_surface;
319 AttachmentPack m_attachmentPack;
320 QClearBuffers::BufferTypeFlags m_clearBuffer;
321 float m_clearDepthValue;
322 int m_clearStencilValue;
323 ClearBufferInfo m_globalClearColorBuffer; // global ClearColor
324 QVector<ClearBufferInfo> m_specificClearColorBuffers; // different draw buffers with distinct colors
325 RenderStateSet *m_stateSet;
326 bool m_noDraw:1;
327 bool m_compute:1;
328 bool m_frustumCulling:1;
329 int m_workGroups[3];
330 QMemoryBarrier::Operations m_memoryBarrier;
331 QVector<Qt3DCore::QNodeId> m_insertFenceIds;
332 QVector<QWaitFenceData> m_waitFences;
333
334 // We do not use pointers to RenderNodes or Drawable's here so that the
335 // render aspect is free to change the drawables on the next frame whilst
336 // the render thread is submitting these commands.
337 QVector<RenderCommand *> m_commands;
338 mutable QVector<LightSource> m_lightSources;
339 EnvironmentLight *m_environmentLight;
340
341 MaterialParameterGathererData m_parameters;
342
343 enum StandardUniform
344 {
345 ModelMatrix,
346 ViewMatrix,
347 ProjectionMatrix,
348 ModelViewMatrix,
349 ViewProjectionMatrix,
350 ModelViewProjectionMatrix,
351 InverseModelMatrix,
352 InverseViewMatrix,
353 InverseProjectionMatrix,
354 InverseModelViewMatrix,
355 InverseViewProjectionMatrix,
356 InverseModelViewProjectionMatrix,
357 ModelNormalMatrix,
358 ModelViewNormalMatrix,
359 ViewportMatrix,
360 InverseViewportMatrix,
361 AspectRatio,
362 Time,
363 Exposure,
364 Gamma,
365 EyePosition,
366 SkinningPalette
367 };
368
369 typedef QHash<int, StandardUniform> StandardUniformsNameToTypeHash;
370 static StandardUniformsNameToTypeHash ms_standardUniformSetters;
371 static StandardUniformsNameToTypeHash initializeStandardUniformSetters();
372
373 UniformValue standardUniformValue(StandardUniform standardUniformType,
374 Entity *entity,
375 const Matrix4x4 &model) const;
376
377 void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
378 void setStandardUniformValue(ShaderParameterPack &uniformPack,
379 int glslNameId,
380 int nameId,
381 Entity *entity,
382 const Matrix4x4 &worldTransform) const;
383 void setUniformBlockValue(ShaderParameterPack &uniformPack,
384 Shader *shader,
385 const ShaderUniformBlock &block,
386 const UniformValue &value) const;
387 void setShaderStorageValue(ShaderParameterPack &uniformPack,
388 Shader *shader,
389 const ShaderStorageBlock &block,
390 const UniformValue &value) const;
391 void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
392 Shader *shader,
393 ShaderData *shaderData,
394 const QString &structName) const;
395};
396
397} // namespace Render
398} // namespace Qt3DRender
399
400QT_END_NAMESPACE
401
402#endif // QT3DRENDER_RENDER_RENDERVIEW_H
403