11#include "../utils/qssgassert_p.h"
13#include <QtQuick/private/qsgrenderer_p.h>
14#include <qtquick3d_tracepoints_p.h>
16#include <QtQuick3D/QQuick3DObject>
21 const auto &scissorCenter = scissorRect.
center();
22 const auto &viewCenter = viewportRect.
center();
23 const float scaleX = viewportRect.
width() / float(scissorRect.
width());
24 const float scaleY = viewportRect.
height() / float(scissorRect.
height());
25 const float dx = 2 * (viewCenter.x() - scissorCenter.x()) / scissorRect.
width();
26 const float dyRect = isYUp ? (scissorCenter.y() - viewCenter.y())
27 : (viewCenter.y() - scissorCenter.y());
28 const float dy = 2 * dyRect / scissorRect.
height();
31 0.0f, scaleY, 0.0f, dy,
32 0.0f, 0.0f, 1.0f, 0.0f,
33 0.0f, 0.0f, 0.0f, 1.0f);
45 const auto &renderedDepthWriteObjects =
data.getSortedRenderedDepthWriteObjects();
46 const auto &renderedOpaqueDepthPrepassObjects =
data.getSortedrenderedOpaqueDepthPrepassObjects();
50 for (
const auto &handles : { &renderedDepthWriteObjects, &renderedOpaqueDepthPrepassObjects }) {
51 for (
const auto &
handle : *handles) {
52 if (
handle.obj->renderableFlags.castsShadows())
64 ps =
data.getPipelineState();
71 const auto &sortedOpaqueObjects =
data.getSortedOpaqueRenderableObjects();
72 const auto &sortedTransparentObjects =
data.getSortedTransparentRenderableObjects();
73 const auto [casting, receiving] = calculateSortedObjectBounds(sortedOpaqueObjects,
74 sortedTransparentObjects);
93 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
94 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
101 rhiRenderShadowMap(rhiCtx.get(),
135 ps =
data.getPipelineState();
143 const auto &sortedOpaqueObjects =
data.getSortedOpaqueRenderableObjects();
144 const auto &sortedTransparentObjects =
data.getSortedTransparentRenderableObjects();
150 for (
const auto &handles : { &sortedOpaqueObjects, &sortedTransparentObjects }) {
151 for (
const auto &
handle : *handles) {
172 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
173 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
179 const auto &
data = *
renderer.getLayerGlobalRenderProperties().layer.renderData;
186 rhiRenderReflectionMap(rhiCtx.get(),
222 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
223 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
225 ps =
data.getPipelineState();
231 const bool hasItem2Ds =
data.renderableItem2Ds.
isEmpty();
241 rhiPrepareDepthPass(rhiCtx.get(),
this,
ps, rhiCtx->mainRenderPassDescriptor(),
data,
244 rhiCtx->mainPassSampleCount());
245 }
else if (rhiPrepareDepthPass(rhiCtx.get(),
this,
ps, rhiCtx->mainRenderPassDescriptor(),
data,
248 rhiCtx->mainPassSampleCount())) {
260 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
261 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
263 bool needsSetViewport =
true;
300 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
301 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
310 ps =
data.getPipelineState();
311 const auto &layerPrepResult =
data.layerPrepResult;
312 const bool ready = rhiPrepareAoTexture(rhiCtx.get(), layerPrepResult->textureDimensions(), &
rhiAoTexture);
334 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
335 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
343 rhiRenderAoTexture(rhiCtx.get(),
371 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
372 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
373 const auto &layerPrepResult =
data.layerPrepResult;
375 ps =
data.getPipelineState();
404 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
405 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
410 bool needsSetViewport =
true;
444 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
445 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
449 const auto &layerPrepResult =
data.layerPrepResult;
450 wantsMips = layerPrepResult->flags.requiresMipmapsForScreenTexture();
452 const auto &renderedOpaqueDepthPrepassObjects =
data.getSortedrenderedOpaqueDepthPrepassObjects();
453 const auto &renderedDepthWriteObjects =
data.getSortedRenderedDepthWriteObjects();
454 ps =
data.getPipelineState();
462 if (!
data.plainSkyBoxPrepared) {
463 data.plainSkyBoxPrepared =
true;
469 const bool depthTestEnableDefault = layerEnableDepthTest && (!
sortedOpaqueObjects.
isEmpty() || !renderedOpaqueDepthPrepassObjects.isEmpty() || !renderedDepthWriteObjects.isEmpty());
507 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
508 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
514 const auto &
layer =
renderer.getLayerGlobalRenderProperties().layer;
527 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &
ps, srb, rpDesc, {});
530 auto shaderPipeline =
renderer.getRhiSkyBoxCubeShader();
535 renderer.rhiCubeRenderer()->recordRenderCube(rhiCtx.get(), &
ps, srb, rpDesc, {});
537 bool needsSetViewport =
true;
539 rhiRenderRenderable(rhiCtx.get(),
ps, *
handle.obj, &needsSetViewport);
543 rub = rhiCtx->rhi()->nextResourceUpdateBatch();
579 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
580 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
584 ps =
data.getPipelineState();
594 if (!
data.plainSkyBoxPrepared) {
595 data.plainSkyBoxPrepared =
true;
601 const auto &clippingFrustum =
data.clippingFrustum;
602 const auto &opaqueObjects =
data.getSortedOpaqueRenderableObjects();
603 const auto &transparentObject =
data.getSortedTransparentRenderableObjects();
604 if (clippingFrustum.has_value()) {
613 const auto &renderedOpaqueDepthPrepassObjects =
data.getSortedrenderedOpaqueDepthPrepassObjects();
614 const auto &renderedDepthWriteObjects =
data.getSortedRenderedDepthWriteObjects();
615 const bool depthTestEnableDefault = layerEnableDepthTest && (!
sortedOpaqueObjects.
isEmpty() || !renderedOpaqueDepthPrepassObjects.isEmpty() || !renderedDepthWriteObjects.isEmpty());;
634 const int samples = rhiCtx->mainPassSampleCount();
665 for (
const auto &item2D: std::as_const(
item2Ds)) {
667 if (!item2D->m_renderer)
669 if (item2D->m_renderer && item2D->m_renderer->currentRhi() !=
renderer.contextInterface()->rhi()) {
670 static bool contextWarningShown =
false;
671 if (!contextWarningShown) {
672 qWarning () <<
"Scene with embedded 2D content can only be rendered in one window.";
673 contextWarningShown =
true;
678 auto layerPrepResult =
data.layerPrepResult;
680 const auto &renderTarget = rhiCtx->renderTarget();
681 item2D->m_renderer->setDevicePixelRatio(renderTarget->devicePixelRatio());
683 if (
layer.scissorRect.isValid()) {
684 QRect effScissor =
layer.scissorRect & layerPrepResult->viewport.toRect();
687 rhiCtx->rhi()->isYUpInNDC());
688 item2D->m_renderer->setProjectionMatrix(correctionMat * item2D->MVP);
689 item2D->m_renderer->setViewportRect(effScissor);
691 item2D->m_renderer->setProjectionMatrix(item2D->MVP);
692 item2D->m_renderer->setViewportRect(correctViewportCoordinates(layerPrepResult->viewport,
deviceRect));
694 item2D->m_renderer->setDeviceRect(
deviceRect);
699 if (!item2D->m_rp->isCompatible(rhiCtx->mainRenderPassDescriptor()))
700 std::swap(item2D->m_rp, oldRp);
706 item2D->m_rp = rhiCtx->mainRenderPassDescriptor()->newCompatibleRenderPassDescriptor();
709 item2D->m_renderer->setRenderTarget({ renderTarget, item2D->m_rp, rhiCtx->commandBuffer() });
711 item2D->m_renderer->prepareSceneInline();
727 if (
layer.gridEnabled)
731 const auto &debugDraw =
renderer.contextInterface()->debugDrawSystem();
732 if (debugDraw && debugDraw->hasContent()) {
734 debugDraw->prepareGeometry(rhiCtx.get(), rub);
742 camera->calculateViewProjectionMatrix(viewProjection);
743 viewProjection = rhiCtx->rhi()->clipSpaceCorrMatrix() * viewProjection;
744 memcpy(ubufData, viewProjection.
constData(), 64);
749 dcd.
srb = rhiCtx->srb(bindings);
751 rhiCtx->commandBuffer()->resourceUpdate(rub);
762 const auto &rhiCtx =
renderer.contextInterface()->rhiContext();
763 QSSG_ASSERT(rhiCtx->rhi()->isRecordingFrame(),
return);
766 bool needsSetViewport =
true;
774 rhiRenderRenderable(rhiCtx.get(),
ps, *theObject, &needsSetViewport);
782 const auto &
layer =
renderer.getLayerGlobalRenderProperties().layer;
791 auto shaderPipeline =
renderer.getRhiSkyBoxCubeShader();
796 renderer.rhiCubeRenderer()->recordRenderCube(rhiCtx.get(), &
ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
809 if (
layer.firstEffect)
812 auto shaderPipeline =
renderer.getRhiSkyBoxShader(tonemapMode,
layer.skyBoxIsRgbe8);
817 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &
ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest | QSSGRhiQuadRenderer::RenderBehind });
828 rhiRenderRenderable(rhiCtx.get(),
ps, *theObject, &needsSetViewport);
855 needsSetViewport =
true;
859 rhiRenderRenderable(rhiCtx.get(),
ps, *theObject, &needsSetViewport);
866 if (
layer.gridEnabled) {
870 const auto &shaderPipeline =
renderer.getRhiGridShader();
875 renderer.rhiQuadRenderer()->recordRenderQuad(rhiCtx.get(), &
ps, srb, rpDesc, { QSSGRhiQuadRenderer::DepthTest });
880 const auto &debugDraw =
renderer.contextInterface()->debugDrawSystem();
881 if (debugDraw && debugDraw->hasContent()) {
885 auto shaderPipeline =
renderer.getRhiDebugObjectShader();
891 debugDraw->recordRenderDebugObjects(rhiCtx.get(), &
ps, srb, rpDesc);
909 auto &frameData =
data.getFrameData();
912 if (
p->type() == QSSGRenderExtension::Type::Standalone)
920 if (
p->type() == QSSGRenderExtension::Type::Main)
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRhiRenderableTexture rhiDepthTexture
QSSGRenderableObjectList sortedTransparentObjects
void renderPass(QSSGRenderer &renderer) final
QSSGRenderableObjectList sortedOpaqueObjects
QVector< QSSGRenderItem2D * > item2Ds
QSSGRenderableObjectList sortedScreenTextureObjects
QSSGShaderFeatures shaderFeatures
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRenderableObjectList sortedOpaqueObjects
QSSGRenderableObjectList sortedTransparentObjects
void renderPass(QSSGRenderer &renderer) final
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Static convenience function that returns a QColor constructed from the RGB color values,...
bool isEmpty() const noexcept
void push_back(parameter_type t)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr QPointF center() const noexcept
Returns the center point of the rectangle.
\inmodule QtCore\reentrant
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr int width() const noexcept
Returns the width of the rectangle.
constexpr QPoint center() const noexcept
Returns the center point of the rectangle.
virtual char * beginFullDynamicBufferUpdateForCurrentFrame()
virtual void endFullDynamicBufferUpdateForCurrentFrame()
To be called when the entire contents of the buffer data has been updated in the memory block returne...
virtual bool create()=0
Creates the corresponding native graphics resources.
void generateMips(QRhiTexture *tex)
Enqueues a mipmap generation operation for the specified texture tex.
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
void renderSceneInline() override
QRhi * currentRhi() const
static qsizetype frustumCulling(const QSSGClippingFrustum &clipFrustum, const QSSGRenderableObjectList &renderables, QSSGRenderableObjectList &visibleRenderables)
static QRhiCommandBuffer::BeginPassFlags commonPassFlags()
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
std::shared_ptr< QSSGRenderReflectionMap > reflectionMapManager
QSSGRenderableObjectList reflectionPassObjects
QVector< QSSGRenderReflectionProbe * > reflectionProbes
QSSGRhiGraphicsPipelineState ps
const QSSGRhiRenderableTexture * rhiDepthTexture
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRhiShaderPipelinePtr ssaoShaderPipeline
void renderPass(QSSGRenderer &renderer) final
const QSSGRenderCamera * camera
QSSGRhiGraphicsPipelineState ps
QSSGRhiRenderableTexture rhiAoTexture
struct SSAOMapPass::AmbientOcclusion ambientOcclusion
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
QSSGRhiGraphicsPipelineState ps
QSSGShaderFeatures shaderFeatures
QSSGRenderableObjectList sortedOpaqueObjects
QSSGRhiRenderableTexture rhiScreenTexture
QSSGRenderCamera * camera
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGShaderLightList globalLights
QSSGRenderableObjectList shadowPassObjects
QSSGRhiGraphicsPipelineState ps
QSSGBoxPoints castingObjectsBox
void renderPass(QSSGRenderer &renderer) final
std::shared_ptr< QSSGRenderShadowMap > shadowMapManager
QSSGBoxPoints receivingObjectsBox
void renderPass(QSSGRenderer &renderer) final
QList< QSSGRenderExtension * > extensions
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
void renderPass(QSSGRenderer &renderer) final
QSSGRenderableObjectList renderedOpaqueDepthPrepassObjects
QSSGRhiGraphicsPipelineState ps
void renderPrep(QSSGRenderer &renderer, QSSGLayerRenderData &data) final
QSSGRenderableObjectList renderedDepthWriteObjects
Combined button and popup list for selecting options.
constexpr Initialization Uninitialized
#define QByteArrayLiteral(str)
GLuint64 GLenum void * handle
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_STRING(Type, Payload, Str)
#define QSSG_ASSERT_X(cond, msg, action)
#define QSSG_ASSERT(cond, action)
static QT_BEGIN_NAMESPACE QMatrix4x4 correctMVPForScissor(QRectF viewportRect, QRect scissorRect, bool isYUp)
#define QSSGRHICTX_STAT(ctx, f)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define QStringLiteral(str)
#define Q_TRACE_SCOPE(x,...)
QSvgRenderer * renderer
[0]
QPointer< QSGRenderer > m_renderer
@ EnableDepthPrePass
True when we render a depth pass before.
bool hasTransparency() const
bool isCompletelyTransparent() const
QSSGRenderableObjectFlags renderableFlags
QSSGDepthDrawMode depthWriteMode
QRhiShaderResourceBindings * srb
float slopeScaledDepthBias
QRhiGraphicsPipeline::PolygonMode polygonMode
QRhiGraphicsPipeline::CompareOp depthFunc
const QSSGRhiShaderPipeline * shaderPipeline
QRhiTextureRenderTarget * rt
QRhiRenderPassDescriptor * rpDesc
void addUniformBuffer(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset, int size)
void disableTonemapping()