| 1 | // Copyright (C) 2008-2012 NVIDIA Corporation. |
| 2 | // Copyright (C) 2019 The Qt Company Ltd. |
| 3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
| 4 | |
| 5 | #include "qssgrenderableobjects_p.h" |
| 6 | #include "qssglayerrenderdata_p.h" |
| 7 | |
| 8 | #include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h> |
| 9 | #include <QtQuick3DRuntimeRender/private/qssgrhicustommaterialsystem_p.h> |
| 10 | #include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h> |
| 11 | #include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h> |
| 12 | |
| 13 | QT_BEGIN_NAMESPACE |
| 14 | struct QSSGRenderableImage; |
| 15 | class QSSGSubsetRenderable; |
| 16 | |
| 17 | QSSGModelContext::QSSGModelContext(const QSSGRenderModel &inModel, |
| 18 | const QMatrix4x4 &inGlobalTransform, |
| 19 | const QMatrix3x3 &inNormalMatrix, |
| 20 | const QSSGRenderMvpArray &inModelViewProjections) |
| 21 | : model(inModel) |
| 22 | , globalTransform(inGlobalTransform) |
| 23 | , normalMatrix(inNormalMatrix) |
| 24 | , modelViewProjections(inModelViewProjections) |
| 25 | { |
| 26 | |
| 27 | } |
| 28 | |
| 29 | QSSGSubsetRenderable::QSSGSubsetRenderable(Type type, |
| 30 | QSSGRenderableObjectFlags inFlags, |
| 31 | const QVector3D &inWorldCenterPt, |
| 32 | QSSGRenderer *rendr, |
| 33 | const QSSGRenderSubset &inSubset, |
| 34 | const QSSGModelContext &inModelContext, |
| 35 | float inOpacity, |
| 36 | quint32 inSubsetLevelOfDetail, |
| 37 | const QSSGRenderGraphObject &mat, |
| 38 | QSSGRenderableImage *inFirstImage, |
| 39 | QSSGShaderDefaultMaterialKey inShaderKey, |
| 40 | const QSSGShaderLightListView &inLights, |
| 41 | bool anyLightHasShadows) |
| 42 | : QSSGRenderableObject(type, |
| 43 | inFlags, |
| 44 | inWorldCenterPt, |
| 45 | inSubset.bounds, |
| 46 | inModelContext.model.m_depthBiasSq, |
| 47 | inModelContext.model.instancingLodMin, |
| 48 | inModelContext.model.instancingLodMax) |
| 49 | , subsetLevelOfDetail(inSubsetLevelOfDetail) |
| 50 | , renderer(rendr) |
| 51 | , modelContext(inModelContext) |
| 52 | , subset(inSubset) |
| 53 | , opacity(inOpacity) |
| 54 | , material(mat) |
| 55 | , firstImage(inFirstImage) |
| 56 | , shaderDescription(inShaderKey) |
| 57 | , lights(inLights) |
| 58 | { |
| 59 | if (mat.type == QSSGRenderGraphObject::Type::CustomMaterial) |
| 60 | depthWriteMode = static_cast<const QSSGRenderCustomMaterial *>(&mat)->m_depthDrawMode; |
| 61 | else |
| 62 | depthWriteMode = static_cast<const QSSGRenderDefaultMaterial *>(&mat)->depthDrawMode; |
| 63 | |
| 64 | const bool modelBlendParticle = (inModelContext.model.particleBuffer != nullptr |
| 65 | && inModelContext.model.particleBuffer->particleCount()); |
| 66 | if (modelBlendParticle) |
| 67 | globalBounds = inModelContext.model.particleBuffer->bounds(); |
| 68 | else |
| 69 | globalBounds.transform(inMatrix: inModelContext.globalTransform); |
| 70 | |
| 71 | // Do we need instanced bounds |
| 72 | const QSSGRenderInstanceTable *instanceTable = inModelContext.model.instanceTable; |
| 73 | if (!instanceTable || !anyLightHasShadows || !(inFlags.castsShadows() || inFlags.receivesShadows())) |
| 74 | return; |
| 75 | |
| 76 | // Check for specified instancing shadow bounds |
| 77 | QSSGBounds3 bounds = QSSGBounds3(instanceTable->getShadowBoundsMinimum(), instanceTable->getShadowBoundsMaximum()); |
| 78 | if (!bounds.isEmpty() && bounds.isFinite()) { |
| 79 | globalBoundsInstancing = bounds; |
| 80 | return; |
| 81 | } |
| 82 | |
| 83 | // Calculate instancing shadow bounds |
| 84 | const auto points = globalBounds.toQSSGBoxPointsNoEmptyCheck(); |
| 85 | for (int i = 0; i < instanceTable->count(); ++i) { |
| 86 | const QMatrix4x4 transform = instanceTable->getTransform(index: i); |
| 87 | for (const QVector3D &point : points) { |
| 88 | globalBoundsInstancing.include(v: transform.map(point)); |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | QSSGParticlesRenderable::QSSGParticlesRenderable(QSSGRenderableObjectFlags inFlags, |
| 94 | const QVector3D &inWorldCenterPt, |
| 95 | QSSGRenderer *rendr, |
| 96 | const QMatrix4x4 &inGlobalTransform, |
| 97 | const QSSGRenderParticles &inParticles, |
| 98 | QSSGRenderableImage *inFirstImage, |
| 99 | QSSGRenderableImage *inColorTable, |
| 100 | const QSSGShaderLightListView &inLights, |
| 101 | float inOpacity) |
| 102 | : QSSGRenderableObject(Type::Particles, |
| 103 | inFlags, |
| 104 | inWorldCenterPt, |
| 105 | inParticles.m_particleBuffer.bounds(), |
| 106 | inParticles.m_depthBiasSq) |
| 107 | , renderer(rendr) |
| 108 | , particles(inParticles) |
| 109 | , firstImage(inFirstImage) |
| 110 | , colorTable(inColorTable) |
| 111 | , lights(inLights) |
| 112 | , globalTransform(inGlobalTransform) |
| 113 | , opacity(inOpacity) |
| 114 | { |
| 115 | // Bounds are in global space for _model blend_ particles |
| 116 | globalBounds = inParticles.m_particleBuffer.bounds(); |
| 117 | if (inParticles.type != QSSGRenderParticles::Type::ModelBlendParticle) |
| 118 | globalBounds.transform(inMatrix: inGlobalTransform); |
| 119 | } |
| 120 | |
| 121 | QT_END_NAMESPACE |
| 122 | |