summaryrefslogtreecommitdiffstats
path: root/src/plugins/renderers/opengl/renderer/renderview_p.h
blob: f44d5c3a177ac340efb9254f3d73ce7c71218f9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QT3DRENDER_RENDER_OPENGL_RENDERVIEW_H
#define QT3DRENDER_RENDER_OPENGL_RENDERVIEW_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists for the convenience
// of other Qt classes.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <Qt3DRender/qparameter.h>
#include <Qt3DRender/qclearbuffers.h>
#include <Qt3DRender/qlayerfilter.h>
#include <Qt3DRender/private/clearbuffers_p.h>
#include <Qt3DRender/private/cameralens_p.h>
#include <Qt3DRender/private/attachmentpack_p.h>
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/private/qsortpolicy_p.h>
#include <Qt3DRender/private/lightsource_p.h>
#include <Qt3DRender/private/qmemorybarrier_p.h>
#include <Qt3DRender/private/qrendercapture_p.h>
#include <Qt3DRender/private/qblitframebuffer_p.h>
#include <Qt3DRender/private/waitfence_p.h>
#include <Qt3DRender/private/renderercache_p.h>

#include <Qt3DCore/private/aligned_malloc_p.h>

#include <renderer_p.h>

#include <QColor>
#include <QList>
#include <QMutex>
#include <QSurface>

QT_BEGIN_NAMESPACE

namespace Qt3DRender {

class QRenderPass;

namespace Render {

class NodeManagers;
class RenderPassFilter;
class TechniqueFilter;
class ViewportNode;
class Effect;
class RenderPass;

namespace OpenGL {

class Renderer;
class RenderCommand;

typedef QPair<ShaderUniform, QVariant> ActivePropertyContent;
typedef QPair<QString, ActivePropertyContent > ActiveProperty;

using EntityRenderCommandData = Render::EntityRenderCommandData<RenderCommand>;
using EntityRenderCommandDataView = Render::EntityRenderCommandDataView<RenderCommand>;
using EntityRenderCommandDataViewPtr = Render::EntityRenderCommandDataViewPtr<RenderCommand>;
using EntityRenderCommandDataSubView = Render::EntityRenderCommandDataSubView<RenderCommand>;

struct Q_AUTOTEST_EXPORT ClearBufferInfo
{
    int drawBufferIndex = 0;
    QRenderTargetOutput::AttachmentPoint attchmentPoint = QRenderTargetOutput::Color0;
    QVector4D clearColor;
};

struct Q_AUTOTEST_EXPORT BlitFramebufferInfo
{
    Qt3DCore::QNodeId sourceRenderTargetId;
    Qt3DCore::QNodeId destinationRenderTargetId;
    QRect sourceRect;
    QRect destinationRect;
    Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint;
    Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint;
    QBlitFramebuffer::InterpolationMethod interpolationMethod;
};

// This class is kind of analogous to RenderBin but I want to avoid trampling
// on that until we get this working

class Q_AUTOTEST_EXPORT RenderView
{
public:
    RenderView();
    ~RenderView();

    QT3D_ALIGNED_MALLOC_AND_FREE()

    static void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv,
                                                          const FrameGraphNode *fgLeaf);

    // TODO: Add a way to specify a sort predicate for the RenderCommands
    void sort();

    void setRenderer(Renderer *renderer);
    inline void setSurfaceSize(const QSize &size) Q_DECL_NOTHROW { m_surfaceSize = size; }
    inline Renderer *renderer() const Q_DECL_NOTHROW { return m_renderer; }
    inline NodeManagers *nodeManagers() const Q_DECL_NOTHROW { return m_manager; }
    inline const QSize &surfaceSize() const Q_DECL_NOTHROW { return m_surfaceSize; }
    inline void setDevicePixelRatio(qreal r) Q_DECL_NOTHROW { m_devicePixelRatio = r; }
    inline qreal devicePixelRatio() const Q_DECL_NOTHROW { return m_devicePixelRatio; }

    inline void setRenderCameraLens(CameraLens *renderCameraLens) Q_DECL_NOTHROW { m_renderCameraLens = renderCameraLens; }
    inline CameraLens *renderCameraLens() const Q_DECL_NOTHROW { return m_renderCameraLens; }

    inline void setRenderCameraEntity(Entity *renderCameraNode) Q_DECL_NOTHROW { m_renderCameraNode = renderCameraNode; }
    inline Entity *renderCameraEntity() const Q_DECL_NOTHROW { return m_renderCameraNode; }

    inline void setViewMatrix(const Matrix4x4 &viewMatrix) Q_DECL_NOTHROW { m_viewMatrix = viewMatrix; }
    inline Matrix4x4 viewMatrix() const Q_DECL_NOTHROW { return m_viewMatrix; }

    inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW { m_viewProjectionMatrix = viewProjectionMatrix; }
    inline Matrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW { return m_viewProjectionMatrix; }

    inline void setEyePosition(const Vector3D &eyePos) Q_DECL_NOTHROW { m_eyePos = eyePos; }
    inline Vector3D eyePosition() const Q_DECL_NOTHROW { return m_eyePos; }

    inline void setEyeViewDirection(const Vector3D &dir) Q_DECL_NOTHROW { m_eyeViewDir = dir; }
    inline Vector3D eyeViewDirection() const Q_DECL_NOTHROW { return m_eyeViewDir; }

    inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_layerFilterIds.push_back(layerFilterId); }
    inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_layerFilterIds; }

    inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_proximityFilterIds.push_back(proximityFilterId); }
    inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_proximityFilterIds; }

    inline void appendInsertFenceId(const Qt3DCore::QNodeId setFenceId) { m_insertFenceIds.push_back(setFenceId); }
    // We prefix with get to avoid confusion when it is called
    inline Qt3DCore::QNodeIdVector insertFenceIds() const { return m_insertFenceIds; }

    inline void appendWaitFence(const WaitFence::Data &data) { m_waitFences.push_back(data); }
    inline QList<WaitFence::Data> waitFences() const { return m_waitFences; }

    inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_passFilter = rpFilter; }
    inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_passFilter; }

    inline void setTechniqueFilter(const TechniqueFilter *filter) Q_DECL_NOTHROW { m_techniqueFilter = filter; }
    inline const TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW { return m_techniqueFilter; }

    inline void setRenderCommandDataView(const EntityRenderCommandDataViewPtr &renderCommandDataView) Q_DECL_NOTHROW { m_renderCommandDataView = renderCommandDataView; }
    inline EntityRenderCommandDataViewPtr renderCommandDataView() const Q_DECL_NOTHROW { return m_renderCommandDataView; }

    RenderStateSet *getOrCreateStateSet();
    RenderStateSet *stateSet() const Q_DECL_NOTHROW { return m_stateSet.data(); }

    inline bool noDraw() const Q_DECL_NOTHROW { return m_noDraw; }
    void setNoDraw(bool noDraw) Q_DECL_NOTHROW { m_noDraw = noDraw; }

    inline bool isCompute() const Q_DECL_NOTHROW { return m_compute; }
    void setCompute(bool compute) Q_DECL_NOTHROW { m_compute = compute; }

    void setComputeWorkgroups(int x, int y, int z) Q_DECL_NOTHROW { m_workGroups[0] = x; m_workGroups[1] = y; m_workGroups[2] = z; }
    const int *computeWorkGroups() const Q_DECL_NOTHROW { return m_workGroups; }
    inline bool frustumCulling() const Q_DECL_NOTHROW { return m_frustumCulling; }
    void setFrustumCulling(bool frustumCulling) Q_DECL_NOTHROW { m_frustumCulling = frustumCulling; }
    bool showDebugOverlay() const Q_DECL_NOTHROW { return m_showDebugOverlay; }
    void setShowDebugOverlay(bool showDebugOverlay) Q_DECL_NOTHROW { m_showDebugOverlay = showDebugOverlay; }

    inline void setMaterialParameterTable(const MaterialParameterGathererData &parameters) Q_DECL_NOTHROW { m_parameters = parameters; }

    // TODO: Get rid of this overly complex memory management by splitting out the
    // InnerData as a RenderViewConfig struct. This can be created by setRenderViewConfigFromFrameGraphLeafNode
    // and passed along with the RenderView to the functions that populate the renderview
    inline void setViewport(const QRectF &vp) Q_DECL_NOTHROW { m_viewport = vp; }
    inline QRectF viewport() const Q_DECL_NOTHROW { return m_viewport; }

    inline float gamma() const Q_DECL_NOTHROW { return m_gamma; }
    inline void setGamma(float gamma) Q_DECL_NOTHROW { m_gamma = gamma; }

    // depth and stencil ClearBuffers are cached locally
    // color ClearBuffers are collected, as there may be multiple
    // color buffers to be cleared. we need to apply all these at rendering
    void addClearBuffers(const ClearBuffers *cb);
    inline const std::vector<ClearBufferInfo> &specificClearColorBufferInfo() const { return m_specificClearColorBuffers; }
    inline std::vector<ClearBufferInfo> &specificClearColorBufferInfo() { return m_specificClearColorBuffers; }
    inline ClearBufferInfo globalClearColorBufferInfo() const { return m_globalClearColorBuffer; }

    inline QClearBuffers::BufferTypeFlags clearTypes() const { return m_clearBuffer; }
    inline float clearDepthValue() const { return m_clearDepthValue; }
    inline int clearStencilValue() const { return m_clearStencilValue; }

    RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true);

    EntityRenderCommandData buildDrawRenderCommands(const Entity **entities,
                                                    int offset, int count) const;
    EntityRenderCommandData buildComputeRenderCommands(const Entity **entities,
                                                       int offset, int count) const;

    void updateRenderCommand(const EntityRenderCommandDataSubView &subView);

    void setAttachmentPack(const AttachmentPack &pack) { m_attachmentPack = pack; }
    const AttachmentPack &attachmentPack() const { return m_attachmentPack; }

    void setRenderTargetId(Qt3DCore::QNodeId renderTargetId) Q_DECL_NOTHROW { m_renderTarget = renderTargetId; }
    Qt3DCore::QNodeId renderTargetId() const Q_DECL_NOTHROW { return m_renderTarget; }

    void addSortType(const QList<Qt3DRender::QSortPolicy::SortType> &sortTypes) { m_sortingTypes.append(sortTypes); }

    void setSurface(QSurface *surface) { m_surface = surface; }
    QSurface *surface() const { return m_surface; }

    void setLightSources(const std::vector<LightSource> &lightSources) Q_DECL_NOTHROW { m_lightSources = lightSources; }
    void setEnvironmentLight(EnvironmentLight *environmentLight) Q_DECL_NOTHROW { m_environmentLight = environmentLight; }

    void updateMatrices();

    inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) Q_DECL_NOTHROW { m_renderCaptureNodeId = nodeId; }
    inline const Qt3DCore::QNodeId renderCaptureNodeId() const Q_DECL_NOTHROW { return m_renderCaptureNodeId; }
    inline void setRenderCaptureRequest(const QRenderCaptureRequest& request) Q_DECL_NOTHROW { m_renderCaptureRequest = request; }
    inline const QRenderCaptureRequest renderCaptureRequest() const Q_DECL_NOTHROW { return m_renderCaptureRequest; }

    void setMemoryBarrier(QMemoryBarrier::Operations barrier) Q_DECL_NOTHROW { m_memoryBarrier = barrier; }
    QMemoryBarrier::Operations memoryBarrier() const Q_DECL_NOTHROW { return m_memoryBarrier; }

    bool isDownloadBuffersEnable() const;
    void setIsDownloadBuffersEnable(bool isDownloadBuffersEnable);

    BlitFramebufferInfo blitFrameBufferInfo() const;
    void setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo);

    bool hasBlitFramebufferInfo() const;
    void setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo);

    bool shouldSkipSubmission() const;

    template<typename F>
    inline void forEachCommand(F func) const
    {
        if (!m_renderCommandDataView)
            return;
        m_renderCommandDataView->forEachCommand(func);
    }

    template<typename F>
    inline void forEachCommand(F func)
    {
        if (!m_renderCommandDataView)
            return;
        m_renderCommandDataView->forEachCommand(func);
    }

    inline int commandCount() const { return m_renderCommandDataView ? m_renderCommandDataView->size() : 0; }

private:
    void setShaderAndUniforms(RenderCommand *command,
                              const ParameterInfoList &parameters,
                              const Entity *entity) const;

    void updateLightUniforms(RenderCommand *command,
                             const Entity *entity) const;

    Renderer *m_renderer = nullptr;
    NodeManagers *m_manager = nullptr;
    EntityRenderCommandDataViewPtr m_renderCommandDataView;

    QSize m_surfaceSize;
    float m_devicePixelRatio = 1.0f;
    QRectF m_viewport = QRectF(0.0f, 0.0f, 1.0f, 1.0f);
    float m_gamma = 2.2f;

    Qt3DCore::QNodeId m_renderCaptureNodeId;
    QRenderCaptureRequest m_renderCaptureRequest;
    bool m_isDownloadBuffersEnable = false;

    bool m_hasBlitFramebufferInfo = false;
    BlitFramebufferInfo m_blitFrameBufferInfo;

    QSurface *m_surface = nullptr;
    Qt3DCore::QNodeId m_renderTarget;
    AttachmentPack m_attachmentPack;
    QClearBuffers::BufferTypeFlags m_clearBuffer = QClearBuffers::None;
    float m_clearDepthValue = 1.0f;
    int m_clearStencilValue = 0;
    ClearBufferInfo m_globalClearColorBuffer;               // global ClearColor
    std::vector<ClearBufferInfo> m_specificClearColorBuffers;   // different draw buffers with distinct colors

    QScopedPointer<RenderStateSet> m_stateSet;
    CameraLens *m_renderCameraLens = nullptr;
    Entity *m_renderCameraNode = nullptr;
    const TechniqueFilter *m_techniqueFilter = nullptr;
    const RenderPassFilter *m_passFilter = nullptr;
    bool m_noDraw = false;
    bool m_compute = false;
    bool m_frustumCulling = false;
    bool m_showDebugOverlay = false;
    int m_workGroups[3] = { 1, 1, 1};
    QMemoryBarrier::Operations m_memoryBarrier = QMemoryBarrier::None;
    QList<Qt3DCore::QNodeId> m_insertFenceIds;
    QList<WaitFence::Data> m_waitFences;
    QList<Qt3DRender::QSortPolicy::SortType> m_sortingTypes;
    Qt3DCore::QNodeIdVector m_proximityFilterIds;
    Qt3DCore::QNodeIdVector m_layerFilterIds;
    Matrix4x4 m_viewMatrix;
    Matrix4x4 m_viewProjectionMatrix;
    Vector3D m_eyePos;
    Vector3D m_eyeViewDir;

    MaterialParameterGathererData m_parameters;
    mutable std::vector<LightSource> m_lightSources;
    EnvironmentLight *m_environmentLight = nullptr;

    enum StandardUniform
    {
        ModelMatrix,
        ViewMatrix,
        ProjectionMatrix,
        ModelViewMatrix,
        ViewProjectionMatrix,
        ModelViewProjectionMatrix,
        InverseModelMatrix,
        InverseViewMatrix,
        InverseProjectionMatrix,
        InverseModelViewMatrix,
        InverseViewProjectionMatrix,
        InverseModelViewProjectionMatrix,
        ModelNormalMatrix,
        ModelViewNormalMatrix,
        ViewportMatrix,
        InverseViewportMatrix,
        AspectRatio,
        Time,
        Exposure,
        Gamma,
        EyePosition,
        SkinningPalette
    };

    typedef QHash<int, StandardUniform> StandardUniformsNameToTypeHash;
    static StandardUniformsNameToTypeHash ms_standardUniformSetters;
    static StandardUniformsNameToTypeHash initializeStandardUniformSetters();

    UniformValue standardUniformValue(StandardUniform standardUniformType,
                                      const Entity *entity) const;

    void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
    void setStandardUniformValue(ShaderParameterPack &uniformPack,
                                 int nameId,
                                 const Entity *entity) const;
    void setUniformBlockValue(ShaderParameterPack &uniformPack,
                              const ShaderUniformBlock &block,
                              const UniformValue &value) const;
    void setShaderStorageValue(ShaderParameterPack &uniformPack,
                               const ShaderStorageBlock &block,
                               const UniformValue &value) const;
    void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
                                               const GLShader *shader,
                                               ShaderData *shaderData,
                                               const QString &structName) const;
    void applyParameter(const Parameter *param,
                        RenderCommand *command,
                        const GLShader *shader) const noexcept;
};

} // namespace OpenGL
} // namespace Render
} // namespace Qt3DRender

QT_END_NAMESPACE

#endif // QT3DRENDER_RENDER_OPENGL_ENDERVIEW_H