diff options
Diffstat (limited to 'src/runtimerender/rendererimpl/Qt3DSRenderableObjects.h')
-rw-r--r-- | src/runtimerender/rendererimpl/Qt3DSRenderableObjects.h | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/src/runtimerender/rendererimpl/Qt3DSRenderableObjects.h b/src/runtimerender/rendererimpl/Qt3DSRenderableObjects.h new file mode 100644 index 0000000..a369f7a --- /dev/null +++ b/src/runtimerender/rendererimpl/Qt3DSRenderableObjects.h @@ -0,0 +1,472 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2012 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) 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.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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#pragma once +#ifndef QT3DS_RENDER_IMPL_RENDERABLE_OBJECTS_H +#define QT3DS_RENDER_IMPL_RENDERABLE_OBJECTS_H +#include "Qt3DSRender.h" +#include "foundation/Qt3DSFlags.h" +#include "Qt3DSRenderModel.h" +#include "foundation/Qt3DSContainers.h" +#include "Qt3DSRenderDefaultMaterial.h" +#include "Qt3DSRenderCustomMaterial.h" +#include "Qt3DSRenderText.h" +#include "Qt3DSRenderMesh.h" +#include "Qt3DSRenderShaderKeys.h" +#include "Qt3DSRenderShaderCache.h" +#include "foundation/Qt3DSInvasiveLinkedList.h" +#include "Qt3DSRenderableImage.h" +#include "Qt3DSDistanceFieldRenderer.h" + +namespace qt3ds { +namespace render { + + struct RenderPreparationResultFlagValues + { + enum Enum { + HasTransparency = 1 << 0, + CompletelyTransparent = 1 << 1, + Dirty = 1 << 2, + Pickable = 1 << 3, + DefaultMaterialMeshSubset = 1 << 4, + Text = 1 << 5, + Custom = 1 << 6, + CustomMaterialMeshSubset = 1 << 7, + HasRefraction = 1 << 8, + Path = 1 << 9, + ShadowCaster = 1 << 10, + DistanceField = 1 << 11, + }; + }; + + struct SRenderableObjectFlags : public NVFlags<RenderPreparationResultFlagValues::Enum, QT3DSU32> + { + void ClearOrSet(bool value, RenderPreparationResultFlagValues::Enum enumVal) + { + if (value) + this->operator|=(enumVal); + else + clear(enumVal); + } + + void SetHasTransparency(bool inHasTransparency) + { + ClearOrSet(inHasTransparency, RenderPreparationResultFlagValues::HasTransparency); + } + bool HasTransparency() const + { + return this->operator&(RenderPreparationResultFlagValues::HasTransparency); + } + bool HasRefraction() const + { + return this->operator&(RenderPreparationResultFlagValues::HasRefraction); + } + void SetCompletelyTransparent(bool inTransparent) + { + ClearOrSet(inTransparent, RenderPreparationResultFlagValues::CompletelyTransparent); + } + bool IsCompletelyTransparent() const + { + return this->operator&(RenderPreparationResultFlagValues::CompletelyTransparent); + } + void SetDirty(bool inDirty) + { + ClearOrSet(inDirty, RenderPreparationResultFlagValues::Dirty); + } + bool IsDirty() const { return this->operator&(RenderPreparationResultFlagValues::Dirty); } + void SetPickable(bool inPickable) + { + ClearOrSet(inPickable, RenderPreparationResultFlagValues::Pickable); + } + bool GetPickable() const + { + return this->operator&(RenderPreparationResultFlagValues::Pickable); + } + + // Mutually exclusive values + void SetDefaultMaterialMeshSubset(bool inMeshSubset) + { + ClearOrSet(inMeshSubset, RenderPreparationResultFlagValues::DefaultMaterialMeshSubset); + } + bool IsDefaultMaterialMeshSubset() const + { + return this->operator&(RenderPreparationResultFlagValues::DefaultMaterialMeshSubset); + } + + void SetCustomMaterialMeshSubset(bool inMeshSubset) + { + ClearOrSet(inMeshSubset, RenderPreparationResultFlagValues::CustomMaterialMeshSubset); + } + bool IsCustomMaterialMeshSubset() const + { + return this->operator&(RenderPreparationResultFlagValues::CustomMaterialMeshSubset); + } + + void SetText(bool inText) { ClearOrSet(inText, RenderPreparationResultFlagValues::Text); } + bool IsText() const { return this->operator&(RenderPreparationResultFlagValues::Text); } + + void setDistanceField(bool inText) + { + ClearOrSet(inText, RenderPreparationResultFlagValues::DistanceField); + } + + bool isDistanceField() const + { + return this->operator&(RenderPreparationResultFlagValues::DistanceField); + } + + void SetCustom(bool inCustom) + { + ClearOrSet(inCustom, RenderPreparationResultFlagValues::Custom); + } + bool IsCustom() const { return this->operator&(RenderPreparationResultFlagValues::Custom); } + + void SetPath(bool inPath) { ClearOrSet(inPath, RenderPreparationResultFlagValues::Path); } + bool IsPath() const { return this->operator&(RenderPreparationResultFlagValues::Path); } + + void SetShadowCaster(bool inCaster) + { + ClearOrSet(inCaster, RenderPreparationResultFlagValues::ShadowCaster); + } + bool IsShadowCaster() const + { + return this->operator&(RenderPreparationResultFlagValues::ShadowCaster); + } + }; + + struct SNodeLightEntry + { + SLight *m_Light; + QT3DSU32 m_LightIndex; + SNodeLightEntry *m_NextNode; + SNodeLightEntry() + : m_Light(NULL) + , m_NextNode(NULL) + { + } + SNodeLightEntry(SLight *inLight, QT3DSU32 inLightIndex) + : m_Light(inLight) + , m_LightIndex(inLightIndex) + , m_NextNode(NULL) + { + } + }; + + DEFINE_INVASIVE_SINGLE_LIST(NodeLightEntry); + + IMPLEMENT_INVASIVE_SINGLE_LIST(NodeLightEntry, m_NextNode); + + struct SRenderableObject; + + typedef void (*TRenderFunction)(SRenderableObject &inObject, const QT3DSVec2 &inCameraProperties); + + struct SRenderableObject + { + // Variables used for picking + const QT3DSMat44 &m_GlobalTransform; + const NVBounds3 &m_Bounds; + SRenderableObjectFlags m_RenderableFlags; + // For rough sorting for transparency and for depth + QT3DSVec3 m_WorldCenterPoint; + QT3DSF32 m_CameraDistanceSq; + TessModeValues::Enum m_TessellationMode; + bool m_ShadowCaster; + // For custom renderable objects the render function must be defined + TRenderFunction m_RenderFunction; + TNodeLightEntryList m_ScopedLights; + SRenderableObject(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + const QT3DSMat44 &inGlobalTransform, const NVBounds3 &inBounds, + TessModeValues::Enum inTessMode = TessModeValues::NoTess, + bool inShadowCaster = true, TRenderFunction inFunction = nullptr) + + : m_GlobalTransform(inGlobalTransform) + , m_Bounds(inBounds) + , m_RenderableFlags(inFlags) + , m_WorldCenterPoint(inWorldCenterPt) + , m_CameraDistanceSq(0) + , m_TessellationMode(inTessMode) + , m_ShadowCaster(inShadowCaster) + , m_RenderFunction(inFunction) + { + } + bool operator<(SRenderableObject *inOther) const + { + return m_CameraDistanceSq < inOther->m_CameraDistanceSq; + } + }; + + typedef nvvector<SRenderableObject *> TRenderableObjectList; + + // Different subsets from the same model will get the same + // model context so we can generate the MVP and normal matrix once + // and only once per subset. + struct SModelContext + { + const SModel &m_Model; + QT3DSMat44 m_ModelViewProjection; + QT3DSMat33 m_NormalMatrix; + + SModelContext(const SModel &inModel, const QT3DSMat44 &inViewProjection) + : m_Model(inModel) + { + m_Model.CalculateMVPAndNormalMatrix(inViewProjection, m_ModelViewProjection, + m_NormalMatrix); + } + SModelContext(const SModelContext &inOther) + : m_Model(inOther.m_Model) + { + // The default copy constructor for these objects is pretty darn slow. + memCopy(&m_ModelViewProjection, &inOther.m_ModelViewProjection, + sizeof(m_ModelViewProjection)); + memCopy(&m_NormalMatrix, &inOther.m_NormalMatrix, sizeof(m_NormalMatrix)); + } + }; + + typedef nvvector<SModelContext *> TModelContextPtrList; + + class Qt3DSRendererImpl; + struct SLayerRenderData; + struct SShadowMapEntry; + + struct SSubsetRenderableBase : public SRenderableObject + { + Qt3DSRendererImpl &m_Generator; + const SModelContext &m_ModelContext; + SRenderSubset m_Subset; + QT3DSF32 m_Opacity; + + SSubsetRenderableBase(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SRenderSubset &subset, + const SModelContext &modelContext, QT3DSF32 inOpacity) + + : SRenderableObject(inFlags, inWorldCenterPt, modelContext.m_Model.m_GlobalTransform, + m_Subset.m_Bounds) + , m_Generator(gen) + , m_ModelContext(modelContext) + , m_Subset(subset) + , m_Opacity(inOpacity) + { + } + void RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, + const SCamera &inCamera, SShadowMapEntry *inShadowMapEntry); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec, SRenderableImage *inDisplacementImage, + float inDisplacementAmount); + }; + + /** + * A renderable that corresponds to a subset (a part of a model). + * These are created per subset per layer and are responsible for actually + * rendering this type of object. + */ + struct SSubsetRenderable : public SSubsetRenderableBase + { + const SDefaultMaterial &m_Material; + SRenderableImage *m_FirstImage; + SShaderDefaultMaterialKey m_ShaderDescription; + NVConstDataRef<QT3DSMat44> m_Bones; + + SSubsetRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SRenderSubset &subset, + const SDefaultMaterial &mat, const SModelContext &modelContext, + QT3DSF32 inOpacity, SRenderableImage *inFirstImage, + SShaderDefaultMaterialKey inShaderKey, + NVConstDataRef<QT3DSMat44> inBoneGlobals) + + : SSubsetRenderableBase(inFlags, inWorldCenterPt, gen, subset, modelContext, inOpacity) + , m_Material(mat) + , m_FirstImage(inFirstImage) + , m_ShaderDescription(inShaderKey) + , m_Bones(inBoneGlobals) + { + m_RenderableFlags.SetDefaultMaterialMeshSubset(true); + m_RenderableFlags.SetCustom(false); + m_RenderableFlags.SetText(false); + m_RenderableFlags.setDistanceField(false); + } + + void Render(const QT3DSVec2 &inCameraVec, TShaderFeatureSet inFeatureSet); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec); + + DefaultMaterialBlendMode::Enum getBlendingMode() + { + return m_Material.m_BlendMode; + } + }; + + struct SCustomMaterialRenderable : public SSubsetRenderableBase + { + const SCustomMaterial &m_Material; + SRenderableImage *m_FirstImage; + SShaderDefaultMaterialKey m_ShaderDescription; + + SCustomMaterialRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SRenderSubset &subset, + const SCustomMaterial &mat, const SModelContext &modelContext, + QT3DSF32 inOpacity, SRenderableImage *inFirstImage, + SShaderDefaultMaterialKey inShaderKey) + : SSubsetRenderableBase(inFlags, inWorldCenterPt, gen, subset, modelContext, inOpacity) + , m_Material(mat) + , m_FirstImage(inFirstImage) + , m_ShaderDescription(inShaderKey) + { + m_RenderableFlags.SetCustomMaterialMeshSubset(true); + } + + void Render(const QT3DSVec2 &inCameraVec, const SLayerRenderData &inLayerData, + const SLayer &inLayer, NVDataRef<SLight *> inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture, const NVRenderTexture2D *inSsaoTexture, + TShaderFeatureSet inFeatureSet); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, + NVConstDataRef<SLight *> inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture); + }; + + struct STextScaleAndOffset + { + QT3DSVec2 m_TextOffset; + QT3DSVec2 m_TextScale; + STextScaleAndOffset(const QT3DSVec2 &inTextOffset, const QT3DSVec2 &inTextScale) + : m_TextOffset(inTextOffset) + , m_TextScale(inTextScale) + { + } + STextScaleAndOffset(NVRenderTexture2D &inTexture, const STextTextureDetails &inTextDetails, + const STextRenderInfo &inInfo); + }; + + struct STextRenderable : public SRenderableObject, public STextScaleAndOffset + { + Qt3DSRendererImpl &m_Generator; + const SText &m_Text; + NVRenderTexture2D &m_Texture; + QT3DSMat44 m_ModelViewProjection; + QT3DSMat44 m_ViewProjection; + + STextRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const SText &inText, const NVBounds3 &inBounds, + const QT3DSMat44 &inModelViewProjection, const QT3DSMat44 &inViewProjection, + NVRenderTexture2D &inTextTexture, const QT3DSVec2 &inTextOffset, + const QT3DSVec2 &inTextScale) + : SRenderableObject(inFlags, inWorldCenterPt, inText.m_GlobalTransform, inBounds) + , STextScaleAndOffset(inTextOffset, inTextScale) + , m_Generator(gen) + , m_Text(inText) + , m_Texture(inTextTexture) + , m_ModelViewProjection(inModelViewProjection) + , m_ViewProjection(inViewProjection) + { + m_RenderableFlags.SetDefaultMaterialMeshSubset(false); + m_RenderableFlags.SetCustom(false); + m_RenderableFlags.SetText(true); + m_RenderableFlags.setDistanceField(false); + } + + void Render(const QT3DSVec2 &inCameraVec); + void RenderDepthPass(const QT3DSVec2 &inCameraVec); + }; + +#if QT_VERSION >= QT_VERSION_CHECK(5,12,2) + struct SDistanceFieldRenderable : public SRenderableObject + { + Q3DSDistanceFieldRenderer &m_distanceFieldText; + QT3DSMat44 m_mvp; + SText &m_text; + + SDistanceFieldRenderable(SRenderableObjectFlags flags, QT3DSVec3 worldCenterPt, + SText &text, const NVBounds3 &bounds, const QT3DSMat44 &mvp, + Q3DSDistanceFieldRenderer &distanceFieldText) + : SRenderableObject(flags, worldCenterPt, text.m_GlobalTransform, bounds) + , m_distanceFieldText(distanceFieldText) + , m_mvp(mvp) + , m_text(text) + { + m_RenderableFlags.SetDefaultMaterialMeshSubset(false); + m_RenderableFlags.SetCustom(false); + m_RenderableFlags.SetText(false); + m_RenderableFlags.setDistanceField(true); + m_distanceFieldText.checkAndBuildGlyphs(text); + } + + void Render(const QT3DSVec2 &inCameraVec); + void RenderDepthPass(const QT3DSVec2 &inCameraVec); + }; +#endif + + struct SPathRenderable : public SRenderableObject + { + Qt3DSRendererImpl &m_Generator; + SPath &m_Path; + NVBounds3 m_Bounds; + QT3DSMat44 m_ModelViewProjection; + QT3DSMat33 m_NormalMatrix; + const SGraphObject &m_Material; + QT3DSF32 m_Opacity; + SRenderableImage *m_FirstImage; + SShaderDefaultMaterialKey m_ShaderDescription; + bool m_IsStroke; + + SPathRenderable(SRenderableObjectFlags inFlags, QT3DSVec3 inWorldCenterPt, + Qt3DSRendererImpl &gen, const QT3DSMat44 &inGlobalTransform, + NVBounds3 &inBounds, SPath &inPath, const QT3DSMat44 &inModelViewProjection, + const QT3DSMat33 inNormalMat, const SGraphObject &inMaterial, QT3DSF32 inOpacity, + SShaderDefaultMaterialKey inShaderKey, bool inIsStroke) + + : SRenderableObject(inFlags, inWorldCenterPt, inGlobalTransform, m_Bounds) + , m_Generator(gen) + , m_Path(inPath) + , m_Bounds(inBounds) + , m_ModelViewProjection(inModelViewProjection) + , m_NormalMatrix(inNormalMat) + , m_Material(inMaterial) + , m_Opacity(inOpacity) + , m_FirstImage(NULL) + , m_ShaderDescription(inShaderKey) + , m_IsStroke(inIsStroke) + { + m_RenderableFlags.SetPath(true); + } + void Render(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, + NVConstDataRef<SLight *> inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture, const NVRenderTexture2D *inSsaoTexture, + TShaderFeatureSet inFeatureSet); + + void RenderDepthPass(const QT3DSVec2 &inCameraVec, const SLayer &inLayer, + NVConstDataRef<SLight *> inLights, const SCamera &inCamera, + const NVRenderTexture2D *inDepthTexture); + + void RenderShadowMapPass(const QT3DSVec2 &inCameraVec, const SLight *inLight, + const SCamera &inCamera, SShadowMapEntry *inShadowMapEntry); + }; +} +} + +#endif |