7#include <QtQuick3DRuntimeRender/private/qssgrenderitem2d_p.h>
9#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
10#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
11#include <QtQuick3DRuntimeRender/private/qssgrenderimage_p.h>
12#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
14#include <QtQuick3DRuntimeRender/private/qssgrendereffect_p.h>
15#include <QtQuick3DRuntimeRender/private/qssgrhicustommaterialsystem_p.h>
16#include <QtQuick3DRuntimeRender/private/qssgrendershadercodegenerator_p.h>
17#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h>
18#include <QtQuick3DRuntimeRender/private/qssgperframeallocator_p.h>
19#include <QtQuick3DRuntimeRender/private/qssgrhiquadrenderer_p.h>
20#include <QtQuick3DRuntimeRender/private/qssgrendertexturedata_p.h>
21#include <QtQuick3DRuntimeRender/private/qssglayerrenderdata_p.h>
22#include <QtQuick3DRuntimeRender/private/qssgrhiparticles_p.h>
23#include <QtQuick3DRuntimeRender/private/qssgvertexpipelineimpl_p.h>
27#include <QtQuick3DUtils/private/qquick3dprofiler_p.h>
28#include <QtQuick3DUtils/private/qssgdataref_p.h>
29#include <QtQuick3DUtils/private/qssgutils_p.h>
30#include <QtQuick3DUtils/private/qssgassert_p.h>
31#include <qtquick3d_tracepoints_p.h>
33#include <QtCore/QMutexLocker>
34#include <QtCore/QBitArray>
72void QSSGRenderer::releaseCachedResources()
74 m_rhiQuadRenderer.reset();
75 m_rhiCubeRenderer.reset();
82 m_contextInterface =
nullptr;
83 releaseCachedResources();
89 m_contextInterface->
bufferManager()->cleanupUnreferencedBuffers(m_frameCount, inLayer);
94 m_contextInterface->
bufferManager()->resetUsageCounters(m_frameCount, inLayer);
101 beginLayerRender(*theRenderData);
102 theRenderData->resetForFrame();
103 theRenderData->prepareForRender();
105 return theRenderData->layerPrepResult.flags.wasDirty();
112 QSSG_ASSERT(theRenderData && !theRenderData->renderedCameras.isEmpty(),
return);
114 const auto layerPrepResult = theRenderData->layerPrepResult;
115 if (layerPrepResult.isLayerVisible()) {
119 theRenderData->maybeBakeLightmap();
120 beginLayerRender(*theRenderData);
125 const auto &activePasses = theRenderData->activePasses;
126 for (
const auto &pass : activePasses) {
127 pass->renderPrep(*
this, *theRenderData);
128 if (pass->passType() == QSSGRenderPass::Type::Standalone)
129 pass->renderPass(*
this);
140 QSSG_ASSERT(theRenderData && !theRenderData->renderedCameras.isEmpty(),
return);
141 if (theRenderData->layerPrepResult.isLayerVisible()) {
142 beginLayerRender(*theRenderData);
143 const auto &activePasses = theRenderData->activePasses;
144 for (
const auto &pass : activePasses) {
145 if (pass->passType() == QSSGRenderPass::Type::Main || pass->passType() == QSSGRenderPass::Type::Extension)
146 pass->renderPass(*
this);
152template<
typename Container>
156 if (!rhiCtx->isValid())
161 for (
const auto &resource : resources) {
162 if (resource->type == QSSGRenderGraphObject::Type::Geometry) {
164 bufferManager->releaseGeometry(geometry);
165 }
else if (resource->type == QSSGRenderGraphObject::Type::Model) {
168 }
else if (resource->type == QSSGRenderGraphObject::Type::TextureData) {
170 bufferManager->releaseTextureData(textureData);
171 }
else if (resource->type == QSSGRenderGraphObject::Type::RenderExtension) {
173 bufferManager->releaseExtensionResult(*rext);
196 if (
layer.renderData ==
nullptr)
199 return layer.renderData;
204 m_materialClearDirty.
insert(material);
225 theKey.toString(shaderString, shaderKeyProperties);
232 return maybePipeline;
237 if (!pregenEntries.isEmpty()) {
239 if (foundIt != pregenEntries.cend())
245 return maybePipeline;
256 renderable.shaderDescription,
261 renderable.firstImage,
262 shaderLibraryManager,
270 auto &m_currentLayer =
renderer.m_currentLayer;
271 auto &m_generatedShaderString =
renderer.m_generatedShaderString;
272 const auto &m_contextInterface =
renderer.m_contextInterface;
273 const auto &theCache = m_contextInterface->shaderCache();
274 const auto &shaderProgramGenerator = m_contextInterface->shaderProgramGenerator();
275 const auto &shaderLibraryManager = m_contextInterface->shaderLibraryManager();
281 const bool executeBeginFrame = !(allowRecursion && (m_activeFrameRef++ != 0));
282 if (executeBeginFrame) {
283 m_contextInterface->perFrameAllocator()->reset();
285 resetResourceCounters(&
layer);
291 const bool executeEndFrame = !(allowRecursion && (--m_activeFrameRef != 0));
292 if (executeEndFrame) {
293 cleanupUnreferencedBuffers(&
layer);
296 for (
auto *matObj : std::as_const(m_materialClearDirty)) {
297 if (matObj->type == QSSGRenderGraphObject::Type::CustomMaterial) {
299 }
else if (matObj->type == QSSGRenderGraphObject::Type::DefaultMaterial ||
300 matObj->type == QSSGRenderGraphObject::Type::PrincipledMaterial ||
301 matObj->type == QSSGRenderGraphObject::Type::SpecularGlossyMaterial) {
305 m_materialClearDirty.
clear();
312 return executeEndFrame;
319 const auto &bufferManager =
ctx.bufferManager();
326 return lhs.m_distanceSq < rhs.m_distanceSq;
336 const auto &bufferManager =
ctx.bufferManager();
347 return lhs.m_distanceSq < rhs.m_distanceSq;
355 QVarLengthArray<QSSGRenderNode*>
subset)
360 for (
auto target : subset)
364 return lhs.m_distanceSq < rhs.m_distanceSq;
371 renderer.m_globalPickingEnabled = isEnabled;
381 if (!m_rhiQuadRenderer)
382 m_rhiQuadRenderer = std::make_unique<QSSGRhiQuadRenderer>();
384 return m_rhiQuadRenderer;
389 if (!m_rhiCubeRenderer)
390 m_rhiCubeRenderer = std::make_unique<QSSGRhiCubeRenderer>();
392 return m_rhiCubeRenderer;
398 m_currentLayer = &inLayer;
400void QSSGRenderer::endLayerRender()
402 m_currentLayer =
nullptr;
409 renderables.push_back(&node);
418 bool inPickEverything,
422 for (
const auto &childNode :
layer.children)
423 dfs(childNode, renderables);
425 for (
int idx = renderables.size() - 1; idx >= 0; --idx) {
426 const auto &pickableObject = renderables.at(idx);
438 if (node.
type == QSSGRenderGraphObject::Type::Item2D) {
444 if (node.
type != QSSGRenderGraphObject::Type::Model)
459 const auto &subMeshes = mesh->
subsets;
461 for (
const auto &subMesh : subMeshes)
462 modelBounds.
include(subMesh.bounds);
464 if (modelBounds.isEmpty())
467 const bool instancing =
model.instancing();
470 for (
int instanceIndex = 0; instanceIndex <
instanceCount; ++instanceIndex) {
474 modelTransform =
model.globalInstanceTransform *
model.instanceTable->getTransform(instanceIndex) *
model.localInstanceTransform;
476 modelTransform =
model.globalTransform;
483 if (!hit.intersects())
487 float minRayLength = std::numeric_limits<float>::max();
489 QVector<QSSGRenderRay::IntersectionResult>
results;
492 int resultSubset = 0;
493 for (
const auto &subMesh : subMeshes) {
495 if (!subMesh.bvhRoot.isNull()) {
497 if (hit.intersects()) {
500 float subMeshMinRayLength = std::numeric_limits<float>::max();
501 for (
const auto &subMeshResult : std::as_const(
results)) {
502 if (subMeshResult.rayLengthSquared < subMeshMinRayLength) {
504 subMeshMinRayLength =
result.rayLengthSquared;
510 if (hit.intersects())
513 if (
result.intersects &&
result.rayLengthSquared < minRayLength) {
514 intersectionResult =
result;
515 minRayLength = intersectionResult.rayLengthSquared;
516 resultSubset = subset;
521 if (intersectionResult.intersects)
523 intersectionResult.rayLengthSquared,
524 intersectionResult.relXY,
525 intersectionResult.scenePosition,
526 intersectionResult.localPosition,
527 intersectionResult.faceNormal,
537 const QVector3D p0 = item2D.getGlobalPos();
538 const QVector3D normal = -item2D.getDirection();
541 float intersectionTime = 0;
543 const QVector3D p0l0 = p0 - inRay.origin;
545 if (intersectionTime >= 0) {
547 const QVector3D intersectionPoint = inRay.origin + inRay.direction * intersectionTime;
550 const QVector2D qmlCoordinate(localIntersectionPoint.x(), -localIntersectionPoint.y());
552 intersectionTime * intersectionTime,
555 localIntersectionPoint,
565 auto *m_currentLayer =
renderer.m_currentLayer;
575 auto &shaderMap = m_currentLayer->shaderMap;
586 inRenderable.shaderDescription);
587 auto it = shaderMap.
find(skey);
588 if (
it == shaderMap.
end()) {
596 shaderMap.insert(skey, shaderPipeline);
598 shaderPipeline =
it.value();
601 if (shaderPipeline !=
nullptr) {
602 if (m_currentLayer && !m_currentLayer->renderedCameras.isEmpty())
603 m_currentLayer->ensureCachedCameraDatas();
606 const auto &rhiContext =
renderer.m_contextInterface->rhiContext();
609 return shaderPipeline;
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
QMatrix4x4 inverted(bool *invertible=nullptr) const
Returns the inverse of this matrix.
static FeatureSet toFeatureSet(const T &ssgFeatureSet)
bool isRecordingFrame() const
Class representing 3D range or axis aligned bounding box.
void include(const QVector3D &v)
expands the volume to include v
QSSGRenderMesh * getMeshForPicking(const QSSGRenderModel &model) const
QMutex * meshUpdateMutex()
const std::unique_ptr< QSSGRhiContext > & rhiContext() const
const std::unique_ptr< QSSGBufferManager > & bufferManager() const
static constexpr bool isRenderable(Type type) noexcept
static PickResultList syncPickSubset(const QSSGRenderLayer &layer, QSSGBufferManager &bufferManager, const QSSGRenderRay &ray, QVarLengthArray< QSSGRenderNode * > subset)
static void setRenderContextInterface(QSSGRenderer &renderer, QSSGRenderContextInterface *ctx)
static PickResultList syncPickAll(const QSSGRenderContextInterface &ctx, const QSSGRenderLayer &layer, const QSSGRenderRay &ray)
static void intersectRayWithItem2D(const QSSGRenderRay &inRay, const QSSGRenderItem2D &item2D, PickResultList &outIntersectionResultList)
static void intersectRayWithSubsetRenderable(QSSGBufferManager &bufferManager, const QSSGRenderRay &inRay, const QSSGRenderNode &node, PickResultList &outIntersectionResultList)
static QSSGRhiShaderPipelinePtr generateRhiShaderPipeline(QSSGRenderer &renderer, QSSGSubsetRenderable &inRenderable, const QSSGShaderFeatures &inFeatureSet)
static bool isGlobalPickingEnabled(const QSSGRenderer &renderer)
static void getLayerHitObjectList(const QSSGRenderLayer &layer, QSSGBufferManager &bufferManager, const QSSGRenderRay &ray, bool inPickEverything, PickResultList &outIntersectionResult)
static QSSGRhiShaderPipelinePtr generateRhiShaderPipelineImpl(QSSGSubsetRenderable &renderable, QSSGShaderLibraryManager &shaderLibraryManager, QSSGShaderCache &shaderCache, QSSGProgramGenerator &shaderProgramGenerator, const QSSGShaderDefaultMaterialKeyProperties &shaderKeyProperties, const QSSGShaderFeatures &featureSet, QByteArray &shaderString)
static void setGlobalPickingEnabled(QSSGRenderer &renderer, bool isEnabled)
static QSSGRhiShaderPipelinePtr getShaderPipelineForDefaultMaterial(QSSGRenderer &renderer, QSSGSubsetRenderable &inRenderable, const QSSGShaderFeatures &inFeatureSet)
static PickResultList syncPick(const QSSGRenderContextInterface &ctx, const QSSGRenderLayer &layer, const QSSGRenderRay &ray, QSSGRenderNode *target=nullptr)
bool prepareLayerForRender(QSSGRenderLayer &inLayer)
void rhiRender(QSSGRenderLayer &inLayer)
friend class QSSGLayerRenderData
const std::unique_ptr< QSSGRhiQuadRenderer > & rhiQuadRenderer() const
void rhiPrepare(QSSGRenderLayer &inLayer)
void cleanupResources(QList< QSSGRenderGraphObject * > &resources)
bool endFrame(QSSGRenderLayer &layer, bool allowRecursion=true)
void beginFrame(QSSGRenderLayer &layer, bool allowRecursion=true)
const std::unique_ptr< QSSGRhiCubeRenderer > & rhiCubeRenderer() const
QSSGRenderContextInterface * contextInterface() const
static QSSGRhiContextPrivate * get(QSSGRhiContext *q)
static QSSGRhiContextStats & get(QSSGRhiContext &rhiCtx)
QSSGRhiShaderPipelinePtr tryGetRhiShaderPipeline(const QByteArray &inKey, const QSSGShaderFeatures &inFeatures)
QSSGRhiShaderPipelinePtr newPipelineFromPregenerated(const QByteArray &inKey, const QSSGShaderFeatures &inFeatures, QQsbCollection::Entry entry, const QSSGRenderGraphObject &obj, QSSGRhiShaderPipeline::StageFlags stageFlags={})
QSSGRhiShaderPipelinePtr tryNewPipelineFromPersistentCache(const QByteArray &qsbcKey, const QByteArray &inKey, const QSSGShaderFeatures &inFeatures, QSSGRhiShaderPipeline::StageFlags stageFlags={})
QQsbCollection::EntryMap m_preGeneratedShaderEntries
const_iterator constFind(const T &value) const
iterator find(const T &value)
iterator insert(const T &value)
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
The QVector2D class represents a vector or vertex in 2D space.
The QVector3D class represents a vector or vertex in 3D space.
static constexpr float dotProduct(QVector3D v1, QVector3D v2) noexcept
Returns the dot product of v1 and v2.
QSet< QString >::iterator it
QVector3D Q_QUICK3DUTILS_EXPORT transform(const QMatrix4x4 &m, const QVector3D &v)
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_ID(Type, Payload, POID)
#define QSSG_ASSERT(cond, action)
static void cleanupResourcesImpl(const QSSGRenderContextInterface &rci, const Container &resources)
static void dfs(const QSSGRenderNode &node, RenderableList &renderables)
static QByteArray logPrefix()
QVarLengthArray< const QSSGRenderNode * > RenderableList
#define QSSGRHICTX_STAT(ctx, f)
std::shared_ptr< QSSGRhiShaderPipeline > QSSGRhiShaderPipelinePtr
#define Q_TRACE_SCOPE(x,...)
QSqlQueryModel * model
[16]
QSvgRenderer * renderer
[0]
QByteArray generateSha() const
static QSSGRhiShaderPipelinePtr generateMaterialRhiShader(const QByteArray &inShaderKeyPrefix, QSSGMaterialVertexPipeline &vertexGenerator, const QSSGShaderDefaultMaterialKey &key, const QSSGShaderDefaultMaterialKeyProperties &inProperties, const QSSGShaderFeatures &inFeatureSet, const QSSGRenderGraphObject &inMaterial, const QSSGShaderLightListView &inLights, QSSGRenderableImage *inFirstImage, QSSGShaderLibraryManager &shaderLibraryManager, QSSGShaderCache &theCache)
QVector< QSSGRenderSubset > subsets
static IntersectionResult createIntersectionResult(const RayData &data, const HitResult &hit)
static RayData createRayData(const QMatrix4x4 &globalTransform, const QSSGRenderRay &ray)
static HitResult intersectWithAABBv2(const RayData &data, const QSSGBounds3 &bounds)
const QSSGRenderSubset & subset
const QSSGRenderGraphObject & material