summaryrefslogtreecommitdiffstats
path: root/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp')
m---------src/Runtime/ogl-runtime0
-rw-r--r--src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp2131
2 files changed, 0 insertions, 2131 deletions
diff --git a/src/Runtime/ogl-runtime b/src/Runtime/ogl-runtime
new file mode 160000
+Subproject 2025912174c4cf99270b7439ec3b021e1d089ae
diff --git a/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp b/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp
deleted file mode 100644
index aaf799fd..00000000
--- a/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp
+++ /dev/null
@@ -1,2131 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-#include "Qt3DSRenderCustomMaterialSystem.h"
-#include "Qt3DSRenderCustomMaterialRenderContext.h"
-#include "Qt3DSRenderContextCore.h"
-#include "foundation/Qt3DSFoundation.h"
-#include "foundation/Qt3DSBroadcastingAllocator.h"
-#include "foundation/Qt3DSAtomic.h"
-#include "Qt3DSRenderCustomMaterial.h"
-#include "Qt3DSRenderDynamicObjectSystemCommands.h"
-#include "Qt3DSRenderBufferManager.h"
-#include "Qt3DSRenderResourceManager.h"
-#include "Qt3DSRenderMesh.h"
-#include "Qt3DSRenderCamera.h"
-#include "Qt3DSRenderLight.h"
-#include "Qt3DSRenderLayer.h"
-#include "render/Qt3DSRenderContext.h"
-#include "render/Qt3DSRenderShaderProgram.h"
-#include "render/Qt3DSRenderComputeShader.h"
-#include "foundation/PreAllocatedAllocator.h"
-#include "foundation/SerializationTypes.h"
-#include "foundation/Qt3DSTime.h"
-#include "Qt3DSRenderDynamicObjectSystemUtil.h"
-#include "Qt3DSRenderableImage.h"
-#include "rendererimpl/Qt3DSVertexPipelineImpl.h"
-#include "rendererimpl/Qt3DSRendererImplLayerRenderData.h"
-#include "Qt3DSRenderCustomMaterialShaderGenerator.h"
-#include "Qt3DSRenderModel.h"
-#include "Qt3DSOffscreenRenderKey.h"
-
-using namespace qt3ds::render;
-using namespace qt3ds::render::dynamic;
-using qt3ds::render::NVRenderContextScopedProperty;
-using qt3ds::render::NVRenderCachedShaderProperty;
-using qt3ds::render::NVRenderCachedShaderBuffer;
-
-SCustomMaterialVertexPipeline::SCustomMaterialVertexPipeline(IQt3DSRenderContext *inContext,
- TessModeValues::Enum inTessMode)
- : SVertexPipelineImpl(
- inContext->GetAllocator(), inContext->GetCustomMaterialShaderGenerator(),
- inContext->GetShaderProgramGenerator(), inContext->GetStringTable(), false)
- , m_Context(inContext)
- , m_TessMode(TessModeValues::NoTess)
-{
- if (m_Context->GetRenderContext().IsTessellationSupported()) {
- m_TessMode = inTessMode;
- }
-
- if (m_Context->GetRenderContext().IsGeometryStageSupported()
- && m_TessMode != TessModeValues::NoTess) {
- m_Wireframe = inContext->GetWireframeMode();
- }
-}
-
-void SCustomMaterialVertexPipeline::InitializeTessControlShader()
-{
- if (m_TessMode == TessModeValues::NoTess
- || ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl) == NULL) {
- return;
- }
-
- IShaderStageGenerator &tessCtrlShader(
- *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl));
-
- tessCtrlShader.AddUniform("tessLevelInner", "float");
- tessCtrlShader.AddUniform("tessLevelOuter", "float");
-
- SetupTessIncludes(ShaderGeneratorStages::TessControl, m_TessMode);
-
- tessCtrlShader.Append("void main() {\n");
-
- tessCtrlShader.Append("\tctWorldPos[0] = varWorldPos[0];");
- tessCtrlShader.Append("\tctWorldPos[1] = varWorldPos[1];");
- tessCtrlShader.Append("\tctWorldPos[2] = varWorldPos[2];");
-
- if (m_TessMode == TessModeValues::TessPhong || m_TessMode == TessModeValues::TessNPatch) {
- tessCtrlShader.Append("\tctNorm[0] = varObjectNormal[0];");
- tessCtrlShader.Append("\tctNorm[1] = varObjectNormal[1];");
- tessCtrlShader.Append("\tctNorm[2] = varObjectNormal[2];");
- }
- if (m_TessMode == TessModeValues::TessNPatch) {
- tessCtrlShader.Append("\tctTangent[0] = varObjTangent[0];");
- tessCtrlShader.Append("\tctTangent[1] = varObjTangent[1];");
- tessCtrlShader.Append("\tctTangent[2] = varObjTangent[2];");
- }
-
- tessCtrlShader.Append(
- "\tgl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;");
- tessCtrlShader.Append("\ttessShader( tessLevelOuter, tessLevelInner);\n");
-}
-
-void SCustomMaterialVertexPipeline::InitializeTessEvaluationShader()
-{
- if (m_TessMode == TessModeValues::NoTess
- || ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval) == NULL) {
- return;
- }
-
- IShaderStageGenerator &tessEvalShader(
- *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval));
-
- tessEvalShader.AddUniform("model_view_projection", "mat4");
- tessEvalShader.AddUniform("normal_matrix", "mat3");
-
- SetupTessIncludes(ShaderGeneratorStages::TessEval, m_TessMode);
-
- if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) {
- tessEvalShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib");
- tessEvalShader.AddUniform("model_matrix", "mat4");
- tessEvalShader.AddUniform("displace_tiling", "vec3");
- tessEvalShader.AddUniform("displaceAmount", "float");
- tessEvalShader.AddUniform(m_DisplacementImage->m_Image.m_ImageShaderName.c_str(),
- "sampler2D");
- }
-
- tessEvalShader.Append("void main() {");
-
- if (m_TessMode == TessModeValues::TessNPatch) {
- tessEvalShader.Append("\tctNorm[0] = varObjectNormalTC[0];");
- tessEvalShader.Append("\tctNorm[1] = varObjectNormalTC[1];");
- tessEvalShader.Append("\tctNorm[2] = varObjectNormalTC[2];");
-
- tessEvalShader.Append("\tctTangent[0] = varTangentTC[0];");
- tessEvalShader.Append("\tctTangent[1] = varTangentTC[1];");
- tessEvalShader.Append("\tctTangent[2] = varTangentTC[2];");
- }
-
- tessEvalShader.Append("\tvec4 pos = tessShader( );\n");
-}
-
-void SCustomMaterialVertexPipeline::FinalizeTessControlShader()
-{
- IShaderStageGenerator &tessCtrlShader(
- *ProgramGenerator().GetStage(ShaderGeneratorStages::TessControl));
- // add varyings we must pass through
- typedef TStrTableStrMap::const_iterator TParamIter;
- for (TParamIter iter = m_InterpolationParameters.begin(),
- end = m_InterpolationParameters.end();
- iter != end; ++iter) {
- tessCtrlShader << "\t" << iter->first.c_str()
- << "TC[gl_InvocationID] = " << iter->first.c_str()
- << "[gl_InvocationID];\n";
- }
-}
-
-void SCustomMaterialVertexPipeline::FinalizeTessEvaluationShader()
-{
- IShaderStageGenerator &tessEvalShader(
- *ProgramGenerator().GetStage(ShaderGeneratorStages::TessEval));
-
- eastl::string outExt("");
- if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry)
- outExt = "TE";
-
- // add varyings we must pass through
- typedef TStrTableStrMap::const_iterator TParamIter;
- if (m_TessMode == TessModeValues::TessNPatch) {
- for (TParamIter iter = m_InterpolationParameters.begin(),
- end = m_InterpolationParameters.end();
- iter != end; ++iter) {
- tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str()
- << " = gl_TessCoord.z * " << iter->first.c_str() << "TC[0] + ";
- tessEvalShader << "gl_TessCoord.x * " << iter->first.c_str() << "TC[1] + ";
- tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[2];\n";
- }
-
- // transform the normal
- if (m_GenerationFlags & GenerationFlagValues::WorldNormal)
- tessEvalShader << "\n\tvarNormal" << outExt.c_str()
- << " = normalize(normal_matrix * teNorm);\n";
- // transform the tangent
- if (m_GenerationFlags & GenerationFlagValues::TangentBinormal) {
- tessEvalShader << "\n\tvarTangent" << outExt.c_str()
- << " = normalize(normal_matrix * teTangent);\n";
- // transform the binormal
- tessEvalShader << "\n\tvarBinormal" << outExt.c_str()
- << " = normalize(normal_matrix * teBinormal);\n";
- }
- } else {
- for (TParamIter iter = m_InterpolationParameters.begin(),
- end = m_InterpolationParameters.end();
- iter != end; ++iter) {
- tessEvalShader << "\t" << iter->first.c_str() << outExt.c_str()
- << " = gl_TessCoord.x * " << iter->first.c_str() << "TC[0] + ";
- tessEvalShader << "gl_TessCoord.y * " << iter->first.c_str() << "TC[1] + ";
- tessEvalShader << "gl_TessCoord.z * " << iter->first.c_str() << "TC[2];\n";
- }
-
- // displacement mapping makes only sense with linear tessellation
- if (m_TessMode == TessModeValues::TessLinear && m_DisplacementImage) {
- tessEvalShader
- << "\ttexture_coordinate_info tmp = textureCoordinateInfo( varTexCoord0"
- << outExt.c_str() << ", varTangent" << outExt.c_str() << ", varBinormal"
- << outExt.c_str() << " );" << Endl;
- tessEvalShader << "\ttmp = transformCoordinate( rotationTranslationScale( vec3( "
- "0.000000, 0.000000, 0.000000 ), vec3( 0.000000, 0.000000, "
- "0.000000 ), displace_tiling ), tmp);"
- << Endl;
-
- tessEvalShader << "\tpos.xyz = defaultMaterialFileDisplacementTexture( "
- << m_DisplacementImage->m_Image.m_ImageShaderName.c_str()
- << ", displaceAmount, "
- << "tmp.position.xy";
- tessEvalShader << ", varObjectNormal" << outExt.c_str() << ", pos.xyz );" << Endl;
- tessEvalShader << "\tvarWorldPos" << outExt.c_str() << "= (model_matrix * pos).xyz;"
- << Endl;
- }
-
- // transform the normal
- tessEvalShader << "\n\tvarNormal" << outExt.c_str()
- << " = normalize(normal_matrix * varObjectNormal" << outExt.c_str()
- << ");\n";
- }
-
- tessEvalShader.Append("\tgl_Position = model_view_projection * pos;\n");
-}
-
-// Responsible for beginning all vertex and fragment generation (void main() { etc).
-void SCustomMaterialVertexPipeline::BeginVertexGeneration(QT3DSU32 displacementImageIdx,
- SRenderableImage *displacementImage)
-{
- m_DisplacementIdx = displacementImageIdx;
- m_DisplacementImage = displacementImage;
-
- TShaderGeneratorStageFlags theStages(IShaderProgramGenerator::DefaultFlags());
-
- if (m_TessMode != TessModeValues::NoTess) {
- theStages |= ShaderGeneratorStages::TessControl;
- theStages |= ShaderGeneratorStages::TessEval;
- }
- if (m_Wireframe) {
- theStages |= ShaderGeneratorStages::Geometry;
- }
-
- ProgramGenerator().BeginProgram(theStages);
-
- if (m_TessMode != TessModeValues::NoTess) {
- InitializeTessControlShader();
- InitializeTessEvaluationShader();
- }
- if (m_Wireframe) {
- InitializeWireframeGeometryShader();
- }
-
- IShaderStageGenerator &vertexShader(Vertex());
-
- // thinks we need
- vertexShader.AddInclude("viewProperties.glsllib");
- vertexShader.AddInclude("customMaterial.glsllib");
-
- vertexShader.AddIncoming("attr_pos", "vec3");
- vertexShader << "void main()" << Endl << "{" << Endl;
-
- if (displacementImage) {
- GenerateUVCoords(0);
- if (!HasTessellation()) {
- vertexShader.AddUniform("displaceAmount", "float");
- vertexShader.AddUniform("displace_tiling", "vec3");
- // we create the world position setup here
- // because it will be replaced with the displaced position
- SetCode(GenerationFlagValues::WorldPosition);
- vertexShader.AddUniform("model_matrix", "mat4");
-
- vertexShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib");
- vertexShader.AddUniform(displacementImage->m_Image.m_ImageShaderName.c_str(),
- "sampler2D");
-
- vertexShader << "\ttexture_coordinate_info tmp = textureCoordinateInfo( texCoord0, "
- "varTangent, varBinormal );"
- << Endl;
- vertexShader << "\ttmp = transformCoordinate( rotationTranslationScale( vec3( "
- "0.000000, 0.000000, 0.000000 ), vec3( 0.000000, 0.000000, "
- "0.000000 ), displace_tiling ), tmp);"
- << Endl;
-
- vertexShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( "
- << displacementImage->m_Image.m_ImageShaderName.c_str()
- << ", displaceAmount, "
- << "tmp.position.xy"
- << ", attr_norm, attr_pos );" << Endl;
-
- AddInterpolationParameter("varWorldPos", "vec3");
- vertexShader.Append("\tvec3 local_model_world_position = (model_matrix * "
- "vec4(displacedPos, 1.0)).xyz;");
- AssignOutput("varWorldPos", "local_model_world_position");
- }
- }
-
- if (HasTessellation()) {
- vertexShader.Append("\tgl_Position = vec4(attr_pos, 1.0);");
- } else {
- vertexShader.AddUniform("model_view_projection", "mat4");
- if (displacementImage)
- vertexShader.Append(
- "\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);");
- else
- vertexShader.Append("\tgl_Position = model_view_projection * vec4(attr_pos, 1.0);");
- }
-
- if (HasTessellation()) {
- GenerateWorldPosition();
- GenerateWorldNormal();
- GenerateObjectNormal();
- GenerateVarTangentAndBinormal();
- }
-}
-
-void SCustomMaterialVertexPipeline::BeginFragmentGeneration()
-{
- Fragment().AddUniform("object_opacity", "float");
- Fragment() << "void main()" << Endl << "{" << Endl;
-}
-
-void SCustomMaterialVertexPipeline::AssignOutput(const char8_t *inVarName,
- const char8_t *inVarValue)
-{
- Vertex() << "\t" << inVarName << " = " << inVarValue << ";\n";
-}
-
-void SCustomMaterialVertexPipeline::GenerateUVCoords(QT3DSU32 inUVSet)
-{
- if (inUVSet == 0 && SetCode(GenerationFlagValues::UVCoords))
- return;
- if (inUVSet == 1 && SetCode(GenerationFlagValues::UVCoords1))
- return;
-
- QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1);
-
- if (inUVSet == 0)
- AddInterpolationParameter("varTexCoord0", "vec3");
- else if (inUVSet == 1)
- AddInterpolationParameter("varTexCoord1", "vec3");
-
- DoGenerateUVCoords(inUVSet);
-}
-
-void SCustomMaterialVertexPipeline::GenerateWorldNormal()
-{
- if (SetCode(GenerationFlagValues::WorldNormal))
- return;
- AddInterpolationParameter("varNormal", "vec3");
- DoGenerateWorldNormal();
-}
-
-void SCustomMaterialVertexPipeline::GenerateObjectNormal()
-{
- if (SetCode(GenerationFlagValues::ObjectNormal))
- return;
- DoGenerateObjectNormal();
-}
-
-void SCustomMaterialVertexPipeline::GenerateVarTangentAndBinormal()
-{
- if (SetCode(GenerationFlagValues::TangentBinormal))
- return;
- AddInterpolationParameter("varTangent", "vec3");
- AddInterpolationParameter("varBinormal", "vec3");
- AddInterpolationParameter("varObjTangent", "vec3");
- AddInterpolationParameter("varObjBinormal", "vec3");
- DoGenerateVarTangentAndBinormal();
-}
-
-void SCustomMaterialVertexPipeline::GenerateWorldPosition()
-{
- if (SetCode(GenerationFlagValues::WorldPosition))
- return;
-
- ActiveStage().AddUniform("model_matrix", "mat4");
- AddInterpolationParameter("varWorldPos", "vec3");
- AddInterpolationParameter("varObjPos", "vec3");
- DoGenerateWorldPosition();
-}
-
-// responsible for closing all vertex and fragment generation
-void SCustomMaterialVertexPipeline::EndVertexGeneration(bool customShader)
-{
- if (HasTessellation()) {
- // finalize tess control shader
- FinalizeTessControlShader();
- // finalize tess evaluation shader
- FinalizeTessEvaluationShader();
-
- TessControl().Append("}");
- TessEval().Append("}");
-
- if (m_Wireframe) {
- // finalize geometry shader
- FinalizeWireframeGeometryShader();
- Geometry().Append("}");
- }
- }
-
- if (!customShader)
- Vertex().Append("}");
-}
-
-void SCustomMaterialVertexPipeline::EndFragmentGeneration(bool customShader)
-{
- if (!customShader)
- Fragment().Append("}");
-}
-
-IShaderStageGenerator &SCustomMaterialVertexPipeline::ActiveStage()
-{
- return Vertex();
-}
-
-void SCustomMaterialVertexPipeline::AddInterpolationParameter(const char8_t *inName,
- const char8_t *inType)
-{
- m_InterpolationParameters.insert(eastl::make_pair(Str(inName), Str(inType)));
- Vertex().AddOutgoing(inName, inType);
- Fragment().AddIncoming(inName, inType);
-
- if (HasTessellation()) {
- eastl::string nameBuilder(inName);
- nameBuilder.append("TC");
- TessControl().AddOutgoing(nameBuilder.c_str(), inType);
-
- nameBuilder.assign(inName);
- if (ProgramGenerator().GetEnabledStages() & ShaderGeneratorStages::Geometry) {
- nameBuilder.append("TE");
- Geometry().AddOutgoing(inName, inType);
- }
- TessEval().AddOutgoing(nameBuilder.c_str(), inType);
- }
-}
-
-void SCustomMaterialVertexPipeline::DoGenerateUVCoords(QT3DSU32 inUVSet)
-{
- QT3DS_ASSERT(inUVSet == 0 || inUVSet == 1);
-
- if (inUVSet == 0) {
- Vertex().AddIncoming("attr_uv0", "vec2");
- Vertex() << "\tvec3 texCoord0 = vec3( attr_uv0, 0.0 );" << Endl;
- AssignOutput("varTexCoord0", "texCoord0");
- } else if (inUVSet == 1) {
- Vertex().AddIncoming("attr_uv1", "vec2");
- Vertex() << "\tvec3 texCoord1 = vec3( attr_uv1, 1.0 );" << Endl;
- AssignOutput("varTexCoord1", "texCoord1");
- }
-}
-
-void SCustomMaterialVertexPipeline::DoGenerateWorldNormal()
-{
- IShaderStageGenerator &vertexGenerator(Vertex());
- vertexGenerator.AddIncoming("attr_norm", "vec3");
- vertexGenerator.AddUniform("normal_matrix", "mat3");
-
- if (HasTessellation() == false) {
- Vertex().Append("\tvarNormal = normalize( normal_matrix * attr_norm );");
- }
-}
-
-void SCustomMaterialVertexPipeline::DoGenerateObjectNormal()
-{
- AddInterpolationParameter("varObjectNormal", "vec3");
- Vertex().Append("\tvarObjectNormal = attr_norm;");
-}
-
-void SCustomMaterialVertexPipeline::DoGenerateWorldPosition()
-{
- Vertex().Append("\tvarObjPos = attr_pos;");
- Vertex().Append("\tvec4 worldPos = (model_matrix * vec4(attr_pos, 1.0));");
- AssignOutput("varWorldPos", "worldPos.xyz");
-}
-
-void SCustomMaterialVertexPipeline::DoGenerateVarTangentAndBinormal()
-{
- Vertex().AddIncoming("attr_textan", "vec3");
- Vertex().AddIncoming("attr_binormal", "vec3");
-
- Vertex() << "\tvarTangent = normal_matrix * attr_textan;" << Endl
- << "\tvarBinormal = normal_matrix * attr_binormal;" << Endl;
-
- Vertex() << "\tvarObjTangent = attr_textan;" << Endl << "\tvarObjBinormal = attr_binormal;"
- << Endl;
-}
-
-void SCustomMaterialVertexPipeline::DoGenerateVertexColor()
-{
- Vertex().AddIncoming("attr_color", "vec3");
- Vertex().Append("\tvarColor = attr_color;");
-}
-
-
-struct SMaterialClass
-{
- NVAllocatorCallback *m_Allocator;
- IDynamicObjectClass *m_Class;
- bool m_HasTransparency;
- bool m_HasRefraction;
- bool m_HasDisplacement;
- bool m_AlwaysDirty;
- QT3DSU32 m_ShaderKey;
- QT3DSU32 m_LayerCount;
- QT3DSI32 mRefCount;
- SMaterialClass(NVAllocatorCallback &alloc, IDynamicObjectClass &inCls)
- : m_Allocator(&alloc)
- , m_Class(&inCls)
- , m_HasTransparency(false)
- , m_HasRefraction(false)
- , m_HasDisplacement(false)
- , m_AlwaysDirty(false)
- , m_ShaderKey(0)
- , m_LayerCount(0)
- , mRefCount(0)
- {
- }
-
- ~SMaterialClass() {}
-
- QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(*m_Allocator)
-
- void AfterWrite()
- {
- m_Allocator = NULL;
- m_Class = NULL;
- mRefCount = 0;
- }
-
- void AfterRead(NVAllocatorCallback &alloc, IDynamicObjectClass &inCls)
- {
- m_Allocator = &alloc;
- m_Class = &inCls;
- mRefCount = 0;
- }
-};
-
-typedef nvhash_map<CRegisteredString, NVScopedRefCounted<SMaterialClass>> TStringMaterialMap;
-typedef eastl::pair<CRegisteredString, CRegisteredString> TStrStrPair;
-
-namespace eastl {
-template <>
-struct hash<TStrStrPair>
-{
- size_t operator()(const TStrStrPair &item) const
- {
- return hash<CRegisteredString>()(item.first) ^ hash<CRegisteredString>()(item.second);
- }
-};
-}
-
-struct SShaderMapKey
-{
- TStrStrPair m_Name;
- eastl::vector<SShaderPreprocessorFeature> m_Features;
- TessModeValues::Enum m_TessMode;
- bool m_WireframeMode;
- SShaderDefaultMaterialKey m_MaterialKey;
- size_t m_HashCode;
- SShaderMapKey(TStrStrPair inName, TShaderFeatureSet inFeatures, TessModeValues::Enum inTessMode,
- bool inWireframeMode, SShaderDefaultMaterialKey inMaterialKey)
- : m_Name(inName)
- , m_Features(inFeatures.begin(), inFeatures.end())
- , m_TessMode(inTessMode)
- , m_WireframeMode(inWireframeMode)
- , m_MaterialKey(inMaterialKey)
- {
- m_HashCode = eastl::hash<TStrStrPair>()(m_Name)
- ^ HashShaderFeatureSet(toDataRef(m_Features.data(), (QT3DSU32)m_Features.size()))
- ^ eastl::hash<QT3DSU32>()(m_TessMode) ^ eastl::hash<bool>()(m_WireframeMode)
- ^ eastl::hash<size_t>()(inMaterialKey.hash());
- }
- bool operator==(const SShaderMapKey &inKey) const
- {
- return m_Name == inKey.m_Name && m_Features == inKey.m_Features
- && m_TessMode == inKey.m_TessMode && m_WireframeMode == inKey.m_WireframeMode
- && m_MaterialKey == inKey.m_MaterialKey;
- }
-};
-
-namespace eastl {
-template <>
-struct hash<SShaderMapKey>
-{
- size_t operator()(const SShaderMapKey &inKey) const { return inKey.m_HashCode; }
-};
-}
-
-namespace {
-
-struct SCustomMaterialTextureData
-{
- NVScopedRefCounted<NVRenderShaderProgram> m_Shader;
- qt3ds::render::NVRenderCachedShaderProperty<NVRenderTexture2D *> m_Sampler;
- qt3ds::render::NVRenderTexture2D *m_Texture;
- bool m_needsMips;
- volatile QT3DSI32 mRefCount;
-
- SCustomMaterialTextureData(NVRenderShaderProgram &inShader, NVRenderTexture2D *inTexture,
- const char *inTexName, bool needMips)
- : m_Shader(inShader)
- , m_Sampler(inTexName, inShader)
- , m_Texture(inTexture)
- , m_needsMips(needMips)
- , mRefCount(0)
- {
- }
-
- void Set(const SPropertyDefinition *inDefinition)
- {
- if (m_Texture && inDefinition) {
- m_Texture->SetMagFilter(inDefinition->m_MagFilterOp);
- m_Texture->SetMinFilter(inDefinition->m_MinFilterOp);
- m_Texture->SetTextureWrapS(inDefinition->m_CoordOp);
- m_Texture->SetTextureWrapT(inDefinition->m_CoordOp);
- } else if (m_Texture) {
- // set some defaults
- m_Texture->SetMinFilter(NVRenderTextureMinifyingOp::Linear);
- m_Texture->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge);
- m_Texture->SetTextureWrapT(NVRenderTextureCoordOp::ClampToEdge);
- }
-
- if ((m_Texture->GetNumMipmaps() == 0) && m_needsMips)
- m_Texture->GenerateMipmaps();
-
- m_Sampler.Set(m_Texture);
- }
-
- QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator())
-
- static SCustomMaterialTextureData CreateTextureEntry(NVRenderShaderProgram &inShader,
- NVRenderTexture2D *inTexture,
- const char *inTexName, bool needMips)
- {
- return SCustomMaterialTextureData(inShader, inTexture, inTexName, needMips);
- }
-};
-
-typedef eastl::pair<CRegisteredString, NVScopedRefCounted<SCustomMaterialTextureData>>
- TCustomMaterialTextureEntry;
-
-/**
- * Cached tessellation property lookups this is on a per mesh base
- */
-struct SCustomMaterialsTessellationProperties
-{
- NVRenderCachedShaderProperty<QT3DSF32> m_EdgeTessLevel; ///< tesselation value for the edges
- NVRenderCachedShaderProperty<QT3DSF32> m_InsideTessLevel; ///< tesselation value for the inside
- NVRenderCachedShaderProperty<QT3DSF32>
- m_PhongBlend; ///< blending between linear and phong component
- NVRenderCachedShaderProperty<QT3DSVec2>
- m_DistanceRange; ///< distance range for min and max tess level
- NVRenderCachedShaderProperty<QT3DSF32> m_DisableCulling; ///< if set to 1.0 this disables backface
- ///culling optimization in the tess shader
-
- SCustomMaterialsTessellationProperties() {}
- SCustomMaterialsTessellationProperties(NVRenderShaderProgram &inShader)
- : m_EdgeTessLevel("tessLevelOuter", inShader)
- , m_InsideTessLevel("tessLevelInner", inShader)
- , m_PhongBlend("phongBlend", inShader)
- , m_DistanceRange("distanceRange", inShader)
- , m_DisableCulling("disableCulling", inShader)
- {
- }
-};
-
-/* We setup some shared state on the custom material shaders */
-struct SCustomMaterialShader
-{
- NVScopedRefCounted<NVRenderShaderProgram> m_Shader;
- NVRenderCachedShaderProperty<QT3DSMat44> m_ModelMatrix;
- NVRenderCachedShaderProperty<QT3DSMat44> m_ViewProjMatrix;
- NVRenderCachedShaderProperty<QT3DSMat44> m_ViewMatrix;
- NVRenderCachedShaderProperty<QT3DSMat33> m_NormalMatrix;
- NVRenderCachedShaderProperty<QT3DSVec3> m_CameraPos;
- NVRenderCachedShaderProperty<QT3DSMat44> m_ProjMatrix;
- NVRenderCachedShaderProperty<QT3DSMat44> m_ViewportMatrix;
- NVRenderCachedShaderProperty<QT3DSVec2> m_CamProperties;
- NVRenderCachedShaderProperty<NVRenderTexture2D *> m_DepthTexture;
- NVRenderCachedShaderProperty<NVRenderTexture2D *> m_AOTexture;
- NVRenderCachedShaderProperty<NVRenderTexture2D *> m_LightProbe;
- NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeProps;
- NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeOpts;
- NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeRot;
- NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeOfs;
- NVRenderCachedShaderProperty<NVRenderTexture2D *> m_LightProbe2;
- NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbe2Props;
- NVRenderCachedShaderProperty<QT3DSI32> m_LightCount;
- NVRenderCachedShaderProperty<QT3DSI32> m_AreaLightCount;
- NVRenderCachedShaderBuffer<qt3ds::render::NVRenderShaderConstantBuffer *> m_AoShadowParams;
- SCustomMaterialsTessellationProperties m_Tessellation;
- SDynamicShaderProgramFlags m_ProgramFlags;
- volatile QT3DSI32 mRefCount;
- SCustomMaterialShader(NVRenderShaderProgram &inShader, SDynamicShaderProgramFlags inFlags)
- : m_Shader(inShader)
- , m_ModelMatrix("model_matrix", inShader)
- , m_ViewProjMatrix("model_view_projection", inShader)
- , m_ViewMatrix("view_matrix", inShader)
- , m_NormalMatrix("normal_matrix", inShader)
- , m_CameraPos("camera_position", inShader)
- , m_ProjMatrix("view_projection_matrix", inShader)
- , m_ViewportMatrix("viewport_matrix", inShader)
- , m_CamProperties("camera_properties", inShader)
- , m_DepthTexture("depth_sampler", inShader)
- , m_AOTexture("ao_sampler", inShader)
- , m_LightProbe("light_probe", inShader)
- , m_LightProbeProps("light_probe_props", inShader)
- , m_LightProbeOpts("light_probe_opts", inShader)
- , m_LightProbeRot("light_probe_rotation", inShader)
- , m_LightProbeOfs("light_probe_offset", inShader)
- , m_LightProbe2("light_probe2", inShader)
- , m_LightProbe2Props("light_probe2_props", inShader)
- , m_LightCount("uNumLights", inShader)
- , m_AreaLightCount("uNumAreaLights", inShader)
- , m_AoShadowParams("cbAoShadow", inShader)
- , m_Tessellation(inShader)
- , m_ProgramFlags(inFlags)
- , mRefCount(0)
- {
- }
-
- QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Shader->GetRenderContext().GetAllocator())
-};
-
-struct SMaterialOrComputeShader
-{
- SCustomMaterialShader *m_MaterialShader;
- NVRenderShaderProgram *m_ComputeShader;
- SMaterialOrComputeShader()
- : m_MaterialShader(NULL)
- , m_ComputeShader(NULL)
- {
- }
- SMaterialOrComputeShader(SCustomMaterialShader &inMaterialShader)
- : m_MaterialShader(&inMaterialShader)
- , m_ComputeShader(NULL)
- {
- }
- SMaterialOrComputeShader(NVRenderShaderProgram &inComputeShader)
- : m_MaterialShader(NULL)
- , m_ComputeShader(&inComputeShader)
- {
- QT3DS_ASSERT(inComputeShader.GetProgramType() == NVRenderShaderProgram::ProgramType::Compute);
- }
- bool IsValid() const { return m_MaterialShader || m_ComputeShader; }
- bool IsComputeShader() const { return m_ComputeShader != NULL; }
- bool IsMaterialShader() const { return m_MaterialShader != NULL; }
- SCustomMaterialShader &MaterialShader()
- {
- QT3DS_ASSERT(IsMaterialShader());
- return *m_MaterialShader;
- }
- NVRenderShaderProgram &ComputeShader()
- {
- QT3DS_ASSERT(IsComputeShader());
- return *m_ComputeShader;
- }
-};
-
-struct SCustomMaterialBuffer
-{
- CRegisteredString m_Name;
- NVScopedRefCounted<NVRenderFrameBuffer> m_FrameBuffer;
- NVScopedRefCounted<NVRenderTexture2D> m_Texture;
- SAllocateBufferFlags m_Flags;
-
- SCustomMaterialBuffer(CRegisteredString inName, NVRenderFrameBuffer &inFb,
- NVRenderTexture2D &inTexture, SAllocateBufferFlags inFlags)
- : m_Name(inName)
- , m_FrameBuffer(&inFb)
- , m_Texture(&inTexture)
- , m_Flags(inFlags)
- {
- }
- SCustomMaterialBuffer() {}
-};
-
-struct SMaterialSystem;
-typedef nvhash_map<CRegisteredString, NVScopedRefCounted<NVRenderVertexBuffer>>
- TStringVertexBufferMap;
-typedef nvhash_map<CRegisteredString, NVScopedRefCounted<NVRenderInputAssembler>>
- TStringAssemblerMap;
-
-struct SStringMemoryBarrierFlagMap
-{
- const char8_t *m_Name;
- qt3ds::render::NVRenderBufferBarrierValues::Enum m_Value;
- SStringMemoryBarrierFlagMap(const char8_t *nm,
- qt3ds::render::NVRenderBufferBarrierValues::Enum val)
- : m_Name(nm)
- , m_Value(val)
- {
- }
-};
-
-SStringMemoryBarrierFlagMap g_StringMemoryFlagMap[] = {
- SStringMemoryBarrierFlagMap("vertex_attribute",
- qt3ds::render::NVRenderBufferBarrierValues::VertexAttribArray),
- SStringMemoryBarrierFlagMap("element_array",
- qt3ds::render::NVRenderBufferBarrierValues::ElementArray),
- SStringMemoryBarrierFlagMap("uniform_buffer",
- qt3ds::render::NVRenderBufferBarrierValues::UniformBuffer),
- SStringMemoryBarrierFlagMap("texture_fetch",
- qt3ds::render::NVRenderBufferBarrierValues::TextureFetch),
- SStringMemoryBarrierFlagMap("shader_image_access",
- qt3ds::render::NVRenderBufferBarrierValues::ShaderImageAccess),
- SStringMemoryBarrierFlagMap("command_buffer",
- qt3ds::render::NVRenderBufferBarrierValues::CommandBuffer),
- SStringMemoryBarrierFlagMap("pixel_buffer",
- qt3ds::render::NVRenderBufferBarrierValues::PixelBuffer),
- SStringMemoryBarrierFlagMap("texture_update",
- qt3ds::render::NVRenderBufferBarrierValues::TextureUpdate),
- SStringMemoryBarrierFlagMap("buffer_update",
- qt3ds::render::NVRenderBufferBarrierValues::BufferUpdate),
- SStringMemoryBarrierFlagMap("frame_buffer",
- qt3ds::render::NVRenderBufferBarrierValues::Framebuffer),
- SStringMemoryBarrierFlagMap("transform_feedback",
- qt3ds::render::NVRenderBufferBarrierValues::TransformFeedback),
- SStringMemoryBarrierFlagMap("atomic_counter",
- qt3ds::render::NVRenderBufferBarrierValues::AtomicCounter),
- SStringMemoryBarrierFlagMap("shader_storage",
- qt3ds::render::NVRenderBufferBarrierValues::ShaderStorage),
-};
-
-struct SStringBlendFuncMap
-{
- const char8_t *m_Name;
- qt3ds::render::NVRenderSrcBlendFunc::Enum m_Value;
- SStringBlendFuncMap(const char8_t *nm, qt3ds::render::NVRenderSrcBlendFunc::Enum val)
- : m_Name(nm)
- , m_Value(val)
- {
- }
-};
-
-SStringBlendFuncMap g_BlendFuncMap[] = {
-#define QT3DS_RENDER_HANDLE_BLEND_FUNC(nm) \
- SStringBlendFuncMap(#nm, qt3ds::render::NVRenderSrcBlendFunc::nm),
-#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(nm) \
- SStringBlendFuncMap(#nm, qt3ds::render::NVRenderSrcBlendFunc::nm),
- QT3DS_RENDER_ITERATE_BLEND_FUNC
-#undef QT3DS_RENDER_HANDLE_BLEND_FUNC
-#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC
-};
-
-struct SMaterialSystem : public ICustomMaterialSystem
-{
- typedef nvhash_map<SShaderMapKey, NVScopedRefCounted<SCustomMaterialShader>> TShaderMap;
- typedef eastl::pair<CRegisteredString, SImage *> TAllocatedImageEntry;
-
- IQt3DSRenderContextCore &m_CoreContext;
- IQt3DSRenderContext *m_Context;
- mutable qt3ds::render::SPreAllocatedAllocator m_Allocator;
- TStringMaterialMap m_StringMaterialMap;
- TShaderMap m_ShaderMap;
- nvvector<TCustomMaterialTextureEntry> m_TextureEntries;
- nvvector<SCustomMaterialBuffer> m_AllocatedBuffers;
- nvvector<TAllocatedImageEntry> m_AllocatedImages;
- bool m_UseFastBlits;
- eastl::string m_ShaderNameBuilder;
- QT3DSU64 m_LastFrameTime;
- QT3DSF32 m_MillisecondsSinceLastFrame;
- QT3DSI32 mRefCount;
-
- SMaterialSystem(IQt3DSRenderContextCore &ct)
- : m_CoreContext(ct)
- , m_Context(NULL)
- , m_Allocator(ct.GetAllocator())
- , m_StringMaterialMap(ct.GetAllocator(), "SMaterialSystem::m_StringMaterialMap")
- , m_ShaderMap(ct.GetAllocator(), "SMaterialSystem::m_ShaderMap")
- , m_TextureEntries(ct.GetAllocator(), "SMaterialSystem::m_TextureEntries")
- , m_AllocatedBuffers(ct.GetAllocator(), "SMaterialSystem::m_AllocatedBuffers")
- , m_AllocatedImages(ct.GetAllocator(), "SMaterialSystem::m_AllocatedImages")
- , m_UseFastBlits(true)
- , m_LastFrameTime(0)
- , m_MillisecondsSinceLastFrame(0)
- , mRefCount(0)
- {
- }
-
- ~SMaterialSystem()
- {
- while (m_AllocatedBuffers.size())
- m_AllocatedBuffers.replace_with_last(0);
-
- for (QT3DSU32 idx = 0; idx < m_AllocatedImages.size(); ++idx) {
- SImage *pImage = m_AllocatedImages[idx].second;
- QT3DS_FREE(m_CoreContext.GetAllocator(), pImage);
- }
- m_AllocatedImages.clear();
- }
-
- void ReleaseBuffer(QT3DSU32 inIdx)
- {
- // Don't call this on MaterialSystem destroy.
- // This causes issues for scene liftime buffers
- // because the resource manager is destroyed before
- IResourceManager &theManager(m_Context->GetResourceManager());
- SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[inIdx]);
- theEntry.m_FrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0,
- NVRenderTextureOrRenderBuffer());
-
- theManager.Release(*theEntry.m_FrameBuffer);
- theManager.Release(*theEntry.m_Texture);
- m_AllocatedBuffers.replace_with_last(inIdx);
- }
-
- QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_CoreContext.GetAllocator())
-
- bool IsMaterialRegistered(CRegisteredString inStr) override
- {
- return m_StringMaterialMap.find(inStr) != m_StringMaterialMap.end();
- }
-
- bool RegisterMaterialClass(CRegisteredString inName,
- NVConstDataRef<dynamic::SPropertyDeclaration> inProperties) override
- {
- if (IsMaterialRegistered(inName))
- return false;
- m_CoreContext.GetDynamicObjectSystemCore().Register(
- inName, inProperties, sizeof(SCustomMaterial), GraphObjectTypes::CustomMaterial);
- IDynamicObjectClass *theClass =
- m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName);
- if (theClass == NULL) {
- QT3DS_ASSERT(false);
- return false;
- }
- SMaterialClass *theNewClass = QT3DS_NEW(m_Allocator, SMaterialClass)(m_Allocator, *theClass);
- m_StringMaterialMap.insert(eastl::make_pair(inName, theNewClass));
- return true;
- }
-
- SMaterialClass *GetMaterialClass(CRegisteredString inStr)
- {
- TStringMaterialMap::iterator theIter = m_StringMaterialMap.find(inStr);
- if (theIter != m_StringMaterialMap.end())
- return theIter->second;
- return NULL;
- }
-
- const SMaterialClass *GetMaterialClass(CRegisteredString inStr) const
- {
- return const_cast<SMaterialSystem *>(this)->GetMaterialClass(inStr);
- }
-
- virtual NVConstDataRef<SPropertyDefinition>
- GetCustomMaterialProperties(CRegisteredString inCustomMaterialName) const override
- {
- IDynamicObjectClass *theMaterialClass =
- m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inCustomMaterialName);
-
- if (theMaterialClass)
- return theMaterialClass->GetProperties();
-
- return NVConstDataRef<SPropertyDefinition>();
- }
-
- virtual QT3DSU32 FindBuffer(CRegisteredString inName)
- {
- for (QT3DSU32 idx = 0, end = m_AllocatedBuffers.size(); idx < end; ++idx)
- if (m_AllocatedBuffers[idx].m_Name == inName)
- return idx;
- return m_AllocatedBuffers.size();
- }
-
- virtual QT3DSU32 FindAllocatedImage(CRegisteredString inName)
- {
- for (QT3DSU32 idx = 0, end = m_AllocatedImages.size(); idx < end; ++idx)
- if (m_AllocatedImages[idx].first == inName)
- return idx;
- return QT3DSU32(-1);
- }
-
- virtual bool TextureNeedsMips(const SPropertyDefinition *inPropDec,
- qt3ds::render::NVRenderTexture2D *inTexture)
- {
- if (inPropDec && inTexture) {
- return bool((inPropDec->m_MinFilterOp == NVRenderTextureMinifyingOp::LinearMipmapLinear)
- && (inTexture->GetNumMipmaps() == 0));
- }
-
- return false;
- }
-
- virtual void SetTexture(NVRenderShaderProgram &inShader, CRegisteredString inPropName,
- NVRenderTexture2D *inTexture,
- const SPropertyDefinition *inPropDec = NULL, bool needMips = false)
- {
- SCustomMaterialTextureData *theTextureEntry(NULL);
- for (QT3DSU32 idx = 0, end = m_TextureEntries.size(); idx < end && theTextureEntry == NULL;
- ++idx) {
- if (m_TextureEntries[idx].first == inPropName
- && m_TextureEntries[idx].second->m_Shader.mPtr == &inShader
- && m_TextureEntries[idx].second->m_Texture == inTexture) {
- theTextureEntry = m_TextureEntries[idx].second;
- break;
- }
- }
- if (theTextureEntry == NULL) {
- NVScopedRefCounted<SCustomMaterialTextureData> theNewEntry =
- QT3DS_NEW(m_CoreContext.GetAllocator(), SCustomMaterialTextureData)(
- SCustomMaterialTextureData::CreateTextureEntry(inShader, inTexture, inPropName,
- needMips));
- m_TextureEntries.push_back(eastl::make_pair(inPropName, theNewEntry));
- theTextureEntry = theNewEntry.mPtr;
- }
- theTextureEntry->Set(inPropDec);
- }
-
- void SetSubpresentation(NVRenderShaderProgram &inShader, CRegisteredString inPropName,
- NVRenderTexture2D *inTexture,
- const SPropertyDefinition *inPropDec)
- {
- SPropertyDefinition propDef = *inPropDec;
- propDef.m_MinFilterOp = NVRenderTextureMinifyingOp::Linear;
- propDef.m_MagFilterOp = NVRenderTextureMagnifyingOp::Linear;
- SCustomMaterialTextureData::CreateTextureEntry(inShader, inTexture, inPropName, false)
- .Set(&propDef);
- }
-
- void SetPropertyEnumNames(CRegisteredString inName, CRegisteredString inPropName,
- NVConstDataRef<CRegisteredString> inNames) override
- {
- m_CoreContext.GetDynamicObjectSystemCore().SetPropertyEnumNames(inName, inPropName,
- inNames);
- }
-
- void SetPropertyTextureSettings(CRegisteredString inName, CRegisteredString inPropName,
- CRegisteredString inPropPath,
- NVRenderTextureTypeValue::Enum inTexType,
- NVRenderTextureCoordOp::Enum inCoordOp,
- NVRenderTextureMagnifyingOp::Enum inMagFilterOp,
- NVRenderTextureMinifyingOp::Enum inMinFilterOp) override
- {
- SMaterialClass *theClass = GetMaterialClass(inName);
- if (theClass && inTexType == NVRenderTextureTypeValue::Displace) {
- theClass->m_HasDisplacement = true;
- }
- m_CoreContext.GetDynamicObjectSystemCore().SetPropertyTextureSettings(
- inName, inPropName, inPropPath, inTexType, inCoordOp, inMagFilterOp, inMinFilterOp);
- }
-
- void SetMaterialClassShader(CRegisteredString inName, const char8_t *inShaderType,
- const char8_t *inShaderVersion, const char8_t *inShaderData,
- bool inHasGeomShader, bool inIsComputeShader) override
- {
- m_CoreContext.GetDynamicObjectSystemCore().SetShaderData(inName, inShaderData, inShaderType,
- inShaderVersion, inHasGeomShader,
- inIsComputeShader);
- }
-
- SCustomMaterial *CreateCustomMaterial(CRegisteredString inName,
- NVAllocatorCallback &inSceneGraphAllocator) override
- {
- SCustomMaterial *theMaterial = static_cast<SCustomMaterial *>(
- m_CoreContext.GetDynamicObjectSystemCore().CreateInstance(inName,
- inSceneGraphAllocator));
- SMaterialClass *theClass = GetMaterialClass(inName);
-
- if (theMaterial) {
- QT3DSU32 key = 0, count = 0;
- if (theClass) {
- key = theClass->m_ShaderKey;
- count = theClass->m_LayerCount;
- }
- theMaterial->Initialize(key, count);
- }
-
- return theMaterial;
- }
-
- void SetCustomMaterialTransparency(CRegisteredString inName, bool inHasTransparency) override
- {
- SMaterialClass *theClass = GetMaterialClass(inName);
-
- if (theClass == NULL) {
- QT3DS_ASSERT(false);
- return;
- }
-
- theClass->m_HasTransparency = inHasTransparency;
- }
-
- void SetCustomMaterialRefraction(CRegisteredString inName, bool inHasRefraction) override
- {
- SMaterialClass *theClass = GetMaterialClass(inName);
-
- if (theClass == NULL) {
- QT3DS_ASSERT(false);
- return;
- }
-
- theClass->m_HasRefraction = inHasRefraction;
- }
-
- void SetCustomMaterialAlwaysDirty(CRegisteredString inName, bool inIsAlwaysDirty) override
- {
- SMaterialClass *theClass = GetMaterialClass(inName);
-
- if (theClass == NULL) {
- QT3DS_ASSERT(false);
- return;
- }
-
- theClass->m_AlwaysDirty = inIsAlwaysDirty;
- }
-
- void SetCustomMaterialShaderKey(CRegisteredString inName, QT3DSU32 inShaderKey) override
- {
- SMaterialClass *theClass = GetMaterialClass(inName);
-
- if (theClass == NULL) {
- QT3DS_ASSERT(false);
- return;
- }
-
- theClass->m_ShaderKey = inShaderKey;
- }
-
- void SetCustomMaterialLayerCount(CRegisteredString inName, QT3DSU32 inLayerCount) override
- {
- SMaterialClass *theClass = GetMaterialClass(inName);
-
- if (theClass == NULL) {
- QT3DS_ASSERT(false);
- return;
- }
-
- theClass->m_LayerCount = inLayerCount;
- }
-
- void SetCustomMaterialCommands(CRegisteredString inName,
- NVConstDataRef<dynamic::SCommand *> inCommands) override
- {
- m_CoreContext.GetDynamicObjectSystemCore().SetRenderCommands(inName, inCommands);
- }
-
- CRegisteredString GetShaderCacheKey(Qt3DSString &inShaderKeyBuffer, const char8_t *inId,
- const char8_t *inProgramMacro,
- const dynamic::SDynamicShaderProgramFlags &inFlags)
- {
- inShaderKeyBuffer.assign(inId);
- if (inProgramMacro && *inProgramMacro) {
- inShaderKeyBuffer.append("#");
- inShaderKeyBuffer.append(inProgramMacro);
- }
- if (inFlags.IsTessellationEnabled()) {
- inShaderKeyBuffer.append("#");
- inShaderKeyBuffer.append(TessModeValues::toString(inFlags.m_TessMode));
- }
- if (inFlags.IsGeometryShaderEnabled() && inFlags.m_WireframeMode) {
- inShaderKeyBuffer.append("#");
- inShaderKeyBuffer.append(inFlags.wireframeToString(inFlags.m_WireframeMode));
- }
-
- return m_CoreContext.GetStringTable().RegisterStr(inShaderKeyBuffer.c_str());
- }
-
- NVRenderShaderProgram *GetShader(SCustomMaterialRenderContext &inRenderContext,
- const SCustomMaterial &inMaterial,
- const SBindShader &inCommand, TShaderFeatureSet inFeatureSet,
- const dynamic::SDynamicShaderProgramFlags &inFlags)
- {
- ICustomMaterialShaderGenerator &theMaterialGenerator(
- m_Context->GetCustomMaterialShaderGenerator());
-
- // generate key
- Qt3DSString theShaderKeyBuffer;
- CRegisteredString theKey = GetShaderCacheKey(theShaderKeyBuffer, inCommand.m_ShaderPath,
- inCommand.m_ShaderDefine, inFlags);
-
- SCustomMaterialVertexPipeline thePipeline(m_Context,
- inRenderContext.m_Model.m_TessellationMode);
-
- NVRenderShaderProgram *theProgram = theMaterialGenerator.GenerateShader(
- inMaterial, inRenderContext.m_MaterialKey, thePipeline, inFeatureSet,
- inRenderContext.m_Lights, inRenderContext.m_FirstImage,
- (inMaterial.m_hasTransparency || inMaterial.m_hasRefraction),
- "custom material pipeline-- ", inCommand.m_ShaderPath.c_str());
-
- return theProgram;
- }
-
- SMaterialOrComputeShader BindShader(SCustomMaterialRenderContext &inRenderContext,
- const SCustomMaterial &inMaterial,
- const SBindShader &inCommand,
- TShaderFeatureSet inFeatureSet)
- {
- NVRenderShaderProgram *theProgram = NULL;
- eastl::vector<SShaderPreprocessorFeature> features;
- for (int i = 0; i < inFeatureSet.size(); ++i)
- features.push_back(inFeatureSet.mData[i]);
- features.push_back(SShaderPreprocessorFeature(m_Context->GetStringTable()
- .RegisterStr("NO_FRAG_OUTPUT"), true));
- TShaderFeatureSet featureSet(features.data(), features.size());
-
- SDynamicShaderProgramFlags theFlags(inRenderContext.m_Model.m_TessellationMode,
- inRenderContext.m_Subset.m_WireframeMode);
- theFlags.SetTessellationEnabled(inRenderContext.m_Model.m_TessellationMode
- != TessModeValues::NoTess);
- theFlags.SetGeometryShaderEnabled(inRenderContext.m_Subset.m_WireframeMode);
-
- SShaderMapKey skey = SShaderMapKey(
- TStrStrPair(inCommand.m_ShaderPath, inCommand.m_ShaderDefine), featureSet,
- theFlags.m_TessMode, theFlags.m_WireframeMode, inRenderContext.m_MaterialKey);
- eastl::pair<TShaderMap::iterator, bool> theInsertResult(m_ShaderMap.insert(
- eastl::make_pair(skey, NVScopedRefCounted<SCustomMaterialShader>(NULL))));
-
- if (theInsertResult.second) {
- theProgram = GetShader(inRenderContext, inMaterial, inCommand, featureSet, theFlags);
-
- if (theProgram) {
- theInsertResult.first->second =
- QT3DS_NEW(m_Allocator, SCustomMaterialShader)(*theProgram, theFlags);
- }
- } else if (theInsertResult.first->second)
- theProgram = theInsertResult.first->second->m_Shader;
-
- if (theProgram) {
- if (theProgram->GetProgramType() == NVRenderShaderProgram::ProgramType::Graphics) {
- if (theInsertResult.first->second) {
- NVRenderContext &theContext(m_Context->GetRenderContext());
- theContext.SetActiveShader(theInsertResult.first->second->m_Shader);
- }
-
- return *theInsertResult.first->second;
- } else {
- NVRenderContext &theContext(m_Context->GetRenderContext());
- theContext.SetActiveShader(theProgram);
- return *(static_cast<NVRenderShaderProgram *>(theProgram));
- }
- }
- return SMaterialOrComputeShader();
- }
-
- void DoApplyInstanceValue(SCustomMaterial & /* inMaterial */, QT3DSU8 *inDataPtr,
- CRegisteredString inPropertyName,
- NVRenderShaderDataTypes::Enum inPropertyType,
- NVRenderShaderProgram &inShader,
- const SPropertyDefinition &inDefinition)
- {
- qt3ds::render::NVRenderShaderConstantBase *theConstant =
- inShader.GetShaderConstant(inPropertyName);
- using namespace qt3ds::render;
- if (theConstant) {
- if (theConstant->GetShaderConstantType() == inPropertyType) {
- if (inPropertyType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) {
- StaticAssert<sizeof(CRegisteredString)
- == sizeof(NVRenderTexture2DPtr)>::valid_expression();
- CRegisteredString *theStrPtr = reinterpret_cast<CRegisteredString *>(inDataPtr);
- IBufferManager &theBufferManager(m_Context->GetBufferManager());
- IOffscreenRenderManager &theOffscreenRenderer(
- m_Context->GetOffscreenRenderManager());
- NVRenderTexture2D *theTexture = nullptr;
-
- if (theStrPtr->IsValid()) {
- if (theOffscreenRenderer.HasOffscreenRenderer(*theStrPtr)) {
- SOffscreenRenderResult theResult
- = theOffscreenRenderer.GetRenderedItem(*theStrPtr);
- theTexture = theResult.m_Texture;
- if (theTexture) {
- SetSubpresentation(inShader, inPropertyName, theTexture,
- &inDefinition);
- }
- } else {
- SImageTextureData theTextureData
- = theBufferManager.LoadRenderImage(*theStrPtr);
- theTexture = theTextureData.m_Texture;
- if (theTexture) {
- SetTexture(inShader, inPropertyName, theTexture, &inDefinition,
- TextureNeedsMips(&inDefinition, theTexture));
- }
- }
- }
- } else {
- switch (inPropertyType) {
-#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \
- case NVRenderShaderDataTypes::type: \
- inShader.SetPropertyValue(theConstant, *(reinterpret_cast<type *>(inDataPtr))); \
- break;
- ITERATE_QT3DS_SHADER_DATA_TYPES
-#undef HANDLE_QT3DS_SHADER_DATA_TYPE
- default:
- QT3DS_ASSERT(false);
- break;
- }
- }
- } else {
- qCCritical(INVALID_OPERATION,
- "CustomMaterial ApplyInstanceValue command datatype and "
- "shader datatypes differ for property %s",
- inPropertyName.c_str());
- QT3DS_ASSERT(false);
- }
- }
- }
-
- void ApplyInstanceValue(SCustomMaterial &inMaterial, SMaterialClass &inClass,
- NVRenderShaderProgram &inShader, const SApplyInstanceValue &inCommand)
- {
- // sanity check
- if (inCommand.m_PropertyName.IsValid()) {
- bool canGetData =
- inCommand.m_ValueOffset + getSizeofShaderDataType(inCommand.m_ValueType)
- <= inMaterial.m_DataSectionByteSize;
- if (canGetData == false) {
- QT3DS_ASSERT(false);
- return;
- }
- QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + inCommand.m_ValueOffset;
- const SPropertyDefinition *theDefinition =
- inClass.m_Class->FindPropertyByName(inCommand.m_PropertyName);
- if (theDefinition)
- DoApplyInstanceValue(inMaterial, dataPtr, inCommand.m_PropertyName,
- inCommand.m_ValueType, inShader, *theDefinition);
- } else {
- NVConstDataRef<SPropertyDefinition> theDefs = inClass.m_Class->GetProperties();
- for (QT3DSU32 idx = 0, end = theDefs.size(); idx < end; ++idx) {
- const SPropertyDefinition &theDefinition(theDefs[idx]);
- qt3ds::render::NVRenderShaderConstantBase *theConstant =
- inShader.GetShaderConstant(theDefinition.m_Name);
-
- // This is fine, the property wasn't found and we continue, no problem.
- if (!theConstant)
- continue;
- QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + theDefinition.m_Offset;
- DoApplyInstanceValue(inMaterial, dataPtr, theDefinition.m_Name,
- theDefinition.m_DataType, inShader, theDefinition);
- }
- }
- }
-
- void ApplyBlending(const SApplyBlending &inCommand)
- {
- NVRenderContext &theContext(m_Context->GetRenderContext());
-
- theContext.SetBlendingEnabled(true);
-
- qt3ds::render::NVRenderBlendFunctionArgument blendFunc =
- qt3ds::render::NVRenderBlendFunctionArgument(
- inCommand.m_SrcBlendFunc, inCommand.m_DstBlendFunc, inCommand.m_SrcBlendFunc,
- inCommand.m_DstBlendFunc);
-
- qt3ds::render::NVRenderBlendEquationArgument blendEqu(NVRenderBlendEquation::Add,
- NVRenderBlendEquation::Add);
-
- theContext.SetBlendFunction(blendFunc);
- theContext.SetBlendEquation(blendEqu);
- }
-
- // we currently only bind a source texture
- const NVRenderTexture2D *ApplyBufferValue(const SCustomMaterial &inMaterial,
- NVRenderShaderProgram &inShader,
- const SApplyBufferValue &inCommand,
- const NVRenderTexture2D *inSourceTexture)
- {
- const NVRenderTexture2D *theTexture = NULL;
-
- if (inCommand.m_BufferName.IsValid()) {
- QT3DSU32 bufferIdx = FindBuffer(inCommand.m_BufferName);
- if (bufferIdx < m_AllocatedBuffers.size()) {
- SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]);
- theTexture = theEntry.m_Texture;
- } else {
- // we must have allocated the read target before
- qCCritical(INTERNAL_ERROR,
- "CustomMaterial: ApplyBufferValue: Failed to setup read target");
- QT3DS_ASSERT(false);
- }
- } else
- theTexture = inSourceTexture;
-
- if (inCommand.m_ParamName.IsValid()) {
- qt3ds::render::NVRenderShaderConstantBase *theConstant =
- inShader.GetShaderConstant(inCommand.m_ParamName);
-
- if (theConstant) {
- if (theConstant->GetShaderConstantType()
- != NVRenderShaderDataTypes::NVRenderTexture2DPtr) {
- qCCritical(INVALID_OPERATION,
- "CustomMaterial %s: Binding buffer to parameter %s that is not a texture",
- inMaterial.m_ClassName.c_str(), inCommand.m_ParamName.c_str());
- QT3DS_ASSERT(false);
- } else {
- SetTexture(inShader, inCommand.m_ParamName,
- const_cast<NVRenderTexture2D *>(theTexture));
- }
- }
- }
-
- return theTexture;
- }
-
- void AllocateBuffer(const SAllocateBuffer &inCommand, NVRenderFrameBuffer *inTarget)
- {
- STextureDetails theSourceTextureDetails;
- NVRenderTexture2D *theTexture = NULL;
- // get color attachment we always assume at location 0
- if (inTarget) {
- NVRenderTextureOrRenderBuffer theSourceTexture =
- inTarget->GetAttachment(NVRenderFrameBufferAttachments::Color0);
- // we need a texture
- if (theSourceTexture.HasTexture2D()) {
- theSourceTextureDetails = theSourceTexture.GetTexture2D()->GetTextureDetails();
- } else {
- qCCritical(INVALID_OPERATION, "CustomMaterial %s: Invalid source texture",
- inCommand.m_Name.c_str());
- QT3DS_ASSERT(false);
- return;
- }
- } else {
- NVRenderContext &theContext = m_Context->GetRenderContext();
- // if we allocate a buffer based on the default target use viewport to get the dimension
- NVRenderRect theViewport(theContext.GetViewport());
- theSourceTextureDetails.m_Height = theViewport.m_Height;
- theSourceTextureDetails.m_Width = theViewport.m_Width;
- }
-
- QT3DSU32 theWidth = (QT3DSU32)(theSourceTextureDetails.m_Width * inCommand.m_SizeMultiplier);
- QT3DSU32 theHeight = (QT3DSU32)(theSourceTextureDetails.m_Height * inCommand.m_SizeMultiplier);
- NVRenderTextureFormats::Enum theFormat = inCommand.m_Format;
- if (theFormat == NVRenderTextureFormats::Unknown)
- theFormat = theSourceTextureDetails.m_Format;
- IResourceManager &theResourceManager(m_Context->GetResourceManager());
- // size intentionally requiried every loop;
- QT3DSU32 bufferIdx = FindBuffer(inCommand.m_Name);
- if (bufferIdx < m_AllocatedBuffers.size()) {
- SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]);
- STextureDetails theDetails = theEntry.m_Texture->GetTextureDetails();
- if (theDetails.m_Width == theWidth && theDetails.m_Height == theHeight
- && theDetails.m_Format == theFormat) {
- theTexture = theEntry.m_Texture;
- } else {
- ReleaseBuffer(bufferIdx);
- }
- }
-
- if (theTexture == NULL) {
- NVRenderFrameBuffer *theFB(theResourceManager.AllocateFrameBuffer());
- NVRenderTexture2D *theTexture(
- theResourceManager.AllocateTexture2D(theWidth, theHeight, theFormat));
- theTexture->SetMagFilter(inCommand.m_FilterOp);
- theTexture->SetMinFilter(
- static_cast<NVRenderTextureMinifyingOp::Enum>(inCommand.m_FilterOp));
- theTexture->SetTextureWrapS(inCommand.m_TexCoordOp);
- theTexture->SetTextureWrapT(inCommand.m_TexCoordOp);
- theFB->Attach(NVRenderFrameBufferAttachments::Color0, *theTexture);
- m_AllocatedBuffers.push_back(SCustomMaterialBuffer(
- inCommand.m_Name, *theFB, *theTexture, inCommand.m_BufferFlags));
- }
- }
-
- NVRenderFrameBuffer *BindBuffer(const SCustomMaterial &inMaterial, const SBindBuffer &inCommand,
- bool &outClearTarget, QT3DSVec2 &outDestSize)
- {
- NVRenderFrameBuffer *theBuffer = NULL;
- NVRenderTexture2D *theTexture = NULL;
-
- // search for the buffer
- QT3DSU32 bufferIdx = FindBuffer(inCommand.m_BufferName);
- if (bufferIdx < m_AllocatedBuffers.size()) {
- theBuffer = m_AllocatedBuffers[bufferIdx].m_FrameBuffer;
- theTexture = m_AllocatedBuffers[bufferIdx].m_Texture;
- }
-
- if (theBuffer == NULL) {
- qCCritical(INVALID_OPERATION, "Effect %s: Failed to find buffer %s for bind",
- inMaterial.m_ClassName.c_str(), inCommand.m_BufferName.c_str());
- QT3DS_ASSERT(false);
- return NULL;
- }
-
- if (theTexture) {
- STextureDetails theDetails(theTexture->GetTextureDetails());
- m_Context->GetRenderContext().SetViewport(
- NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height));
- outDestSize = QT3DSVec2((QT3DSF32)theDetails.m_Width, (QT3DSF32)theDetails.m_Height);
- outClearTarget = inCommand.m_NeedsClear;
- }
-
- return theBuffer;
- }
-
- void computeScreenCoverage(SCustomMaterialRenderContext &inRenderContext, QT3DSI32 *xMin,
- QT3DSI32 *yMin, QT3DSI32 *xMax, QT3DSI32 *yMax)
- {
- NVRenderContext &theContext(m_Context->GetRenderContext());
- TNVBounds2BoxPoints outPoints;
- QT3DSVec4 projMin(QT3DS_MAX_REAL);
- QT3DSVec4 projMax(-QT3DS_MAX_REAL);
-
- // get points
- inRenderContext.m_Subset.m_Bounds.expand(outPoints);
- for (QT3DSU32 idx = 0; idx < 8; ++idx) {
- QT3DSVec4 homPoint(outPoints[idx], 1.0);
- QT3DSVec4 projPoint = inRenderContext.m_ModelViewProjection.transform(homPoint);
- projPoint /= projPoint.w;
-
- if (projMin.x > projPoint.x)
- projMin.x = projPoint.x;
- if (projMin.y > projPoint.y)
- projMin.y = projPoint.y;
- if (projMin.z > projPoint.z)
- projMin.z = projPoint.z;
-
- if (projMax.x < projPoint.x)
- projMax.x = projPoint.x;
- if (projMax.y < projPoint.y)
- projMax.y = projPoint.y;
- if (projMax.z < projPoint.z)
- projMax.z = projPoint.z;
- }
-
- NVRenderRect theViewport(theContext.GetViewport());
- QT3DSI32 x1 = QT3DSI32(projMax.x * (theViewport.m_Width / 2)
- + (theViewport.m_X + (theViewport.m_Width / 2)));
- QT3DSI32 y1 = QT3DSI32(projMax.y * (theViewport.m_Height / 2)
- + (theViewport.m_Y + (theViewport.m_Height / 2)));
-
- QT3DSI32 x2 = QT3DSI32(projMin.x * (theViewport.m_Width / 2)
- + (theViewport.m_X + (theViewport.m_Width / 2)));
- QT3DSI32 y2 = QT3DSI32(projMin.y * (theViewport.m_Height / 2)
- + (theViewport.m_Y + (theViewport.m_Height / 2)));
-
- if (x1 > x2) {
- *xMin = x2;
- *xMax = x1;
- } else {
- *xMin = x1;
- *xMax = x2;
- }
- if (y1 > y2) {
- *yMin = y2;
- *yMax = y1;
- } else {
- *yMin = y1;
- *yMax = y2;
- }
- }
-
- void BlitFramebuffer(SCustomMaterialRenderContext &inRenderContext,
- const SApplyBlitFramebuffer &inCommand, NVRenderFrameBuffer *inTarget)
- {
- NVRenderContext &theContext(m_Context->GetRenderContext());
- // we change the read/render targets here
- NVRenderContextScopedProperty<NVRenderFrameBuffer *> __framebuffer(
- theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget);
- // we may alter scissor
- NVRenderContextScopedProperty<bool> theScissorEnabled(
- theContext, &NVRenderContext::IsScissorTestEnabled,
- &NVRenderContext::SetScissorTestEnabled);
-
- if (inCommand.m_DestBufferName.IsValid()) {
- QT3DSU32 bufferIdx = FindBuffer(inCommand.m_DestBufferName);
- if (bufferIdx < m_AllocatedBuffers.size()) {
- SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]);
- theContext.SetRenderTarget(theEntry.m_FrameBuffer);
- } else {
- // we must have allocated the read target before
- qCCritical(INTERNAL_ERROR,
- "CustomMaterial: BlitFramebuffer: Failed to setup render target");
- QT3DS_ASSERT(false);
- }
- } else {
- // our dest is the default render target
- theContext.SetRenderTarget(inTarget);
- }
-
- if (inCommand.m_SourceBufferName.IsValid()) {
- QT3DSU32 bufferIdx = FindBuffer(inCommand.m_SourceBufferName);
- if (bufferIdx < m_AllocatedBuffers.size()) {
- SCustomMaterialBuffer &theEntry(m_AllocatedBuffers[bufferIdx]);
- theContext.SetReadTarget(theEntry.m_FrameBuffer);
- theContext.SetReadBuffer(NVReadFaces::Color0);
- } else {
- // we must have allocated the read target before
- qCCritical(INTERNAL_ERROR,
- "CustomMaterial: BlitFramebuffer: Failed to setup read target");
- QT3DS_ASSERT(false);
- }
- } else {
- // our source is the default read target
- // depending on what we render we assume color0 or back
- theContext.SetReadTarget(inTarget);
- NVReadFaces::Enum value = (inTarget) ? NVReadFaces::Color0 : NVReadFaces::Back;
- theContext.SetReadBuffer(value);
- }
-
- NVRenderRect theViewport(theContext.GetViewport());
- theContext.SetScissorTestEnabled(false);
-
- if (!m_UseFastBlits) {
- // only copy sreen amount of pixels
- QT3DSI32 xMin, yMin, xMax, yMax;
- computeScreenCoverage(inRenderContext, &xMin, &yMin, &xMax, &yMax);
-
- // same dimension
- theContext.BlitFramebuffer(xMin, yMin, xMax, yMax, xMin, yMin, xMax, yMax,
- NVRenderClearValues::Color,
- NVRenderTextureMagnifyingOp::Nearest);
- } else {
- // same dimension
- theContext.BlitFramebuffer(
- theViewport.m_X, theViewport.m_Y, theViewport.m_X + theViewport.m_Width,
- theViewport.m_Y + theViewport.m_Height, theViewport.m_X, theViewport.m_Y,
- theViewport.m_X + theViewport.m_Width, theViewport.m_Y + theViewport.m_Height,
- NVRenderClearValues::Color, NVRenderTextureMagnifyingOp::Nearest);
- }
- }
-
- SLayerGlobalRenderProperties
- GetLayerGlobalRenderProperties(SCustomMaterialRenderContext &inRenderContext)
- {
- const SLayer &theLayer = inRenderContext.m_Layer;
- const SLayerRenderData &theData = inRenderContext.m_LayerData;
-
- return SLayerGlobalRenderProperties(
- theLayer, const_cast<SCamera &>(inRenderContext.m_Camera), theData.m_CameraDirection,
- inRenderContext.m_Lights, NVDataRef<QT3DSVec3>(), theData.m_ShadowMapManager.mPtr,
- const_cast<NVRenderTexture2D *>(inRenderContext.m_DepthTexture),
- const_cast<NVRenderTexture2D *>(inRenderContext.m_AOTexture), theLayer.m_LightProbe,
- theLayer.m_LightProbe2, theLayer.m_ProbeHorizon, theLayer.m_ProbeBright,
- theLayer.m_Probe2Window, theLayer.m_Probe2Pos, theLayer.m_Probe2Fade,
- theLayer.m_ProbeFov);
- }
-
- void RenderPass(SCustomMaterialRenderContext &inRenderContext, SCustomMaterialShader &inShader,
- NVRenderTexture2D * /* inSourceTexture */
- ,
- NVRenderFrameBuffer *inFrameBuffer, bool inRenderTargetNeedsClear,
- NVRenderInputAssembler &inAssembler, QT3DSU32 inCount, QT3DSU32 inOffset)
- {
- ICustomMaterialShaderGenerator &theMaterialGenerator(
- m_Context->GetCustomMaterialShaderGenerator());
-
- theMaterialGenerator.SetMaterialProperties(
- *inShader.m_Shader, inRenderContext.m_Material, QT3DSVec2(1.0, 1.0),
- inRenderContext.m_ModelViewProjection, inRenderContext.m_NormalMatrix,
- inRenderContext.m_ModelMatrix, inRenderContext.m_FirstImage, inRenderContext.m_Opacity,
- GetLayerGlobalRenderProperties(inRenderContext));
-
- NVRenderContext &theContext(m_Context->GetRenderContext());
- theContext.SetRenderTarget(inFrameBuffer);
-
- QT3DSVec4 clearColor(0.0);
- NVRenderContextScopedProperty<QT3DSVec4> __clearColor(
- theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor,
- clearColor);
- if (inRenderTargetNeedsClear) {
- theContext.Clear(qt3ds::render::NVRenderClearValues::Color);
- }
-
- // I think the prim type should always be fetched from the
- // current mesh subset setup because there you get the actual draw mode
- // for this frame
- NVRenderDrawMode::Enum theDrawMode = inAssembler.GetPrimitiveType();
-
- // tesselation
- if (inRenderContext.m_Subset.m_PrimitiveType == NVRenderDrawMode::Patches) {
- QT3DSVec2 camProps(inRenderContext.m_Camera.m_ClipNear,
- inRenderContext.m_Camera.m_ClipFar);
- theDrawMode = inRenderContext.m_Subset.m_PrimitiveType;
- inShader.m_Tessellation.m_EdgeTessLevel.Set(inRenderContext.m_Subset.m_EdgeTessFactor);
- inShader.m_Tessellation.m_InsideTessLevel.Set(
- inRenderContext.m_Subset.m_InnerTessFactor);
- // the blend value is hardcoded
- inShader.m_Tessellation.m_PhongBlend.Set(0.75);
- // this should finally be based on some user input
- inShader.m_Tessellation.m_DistanceRange.Set(camProps);
- // enable culling
- inShader.m_Tessellation.m_DisableCulling.Set(0.0);
- }
-
- if (inRenderContext.m_Subset.m_WireframeMode) {
- NVRenderRect theViewport(theContext.GetViewport());
- QT3DSMat44 vpMatrix;
- vpMatrix.column0 = QT3DSVec4((float)theViewport.m_Width / 2.0f, 0.0, 0.0, 0.0);
- vpMatrix.column1 = QT3DSVec4(0.0, (float)theViewport.m_Height / 2.0f, 0.0, 0.0);
- vpMatrix.column2 = QT3DSVec4(0.0, 0.0, 1.0, 0.0);
- vpMatrix.column3 =
- QT3DSVec4((float)theViewport.m_Width / 2.0f + (float)theViewport.m_X,
- (float)theViewport.m_Height / 2.0f + (float)theViewport.m_Y, 0.0, 1.0);
-
- inShader.m_ViewportMatrix.Set(vpMatrix);
- }
-
- theContext.SetInputAssembler(&inAssembler);
-
- theContext.SetCullingEnabled(true);
- QT3DSU32 count = inCount;
- QT3DSU32 offset = inOffset;
-
- theContext.Draw(theDrawMode, count, offset);
- }
-
- void DoRenderCustomMaterial(SCustomMaterialRenderContext &inRenderContext,
- const SCustomMaterial &inMaterial, SMaterialClass &inClass,
- NVRenderFrameBuffer *inTarget, TShaderFeatureSet inFeatureSet)
- {
- NVRenderContext &theContext = m_Context->GetRenderContext();
- SCustomMaterialShader *theCurrentShader(NULL);
-
- NVRenderFrameBuffer *theCurrentRenderTarget(inTarget);
- NVRenderRect theOriginalViewport(theContext.GetViewport());
- NVRenderTexture2D *theCurrentSourceTexture = 0;
-
- // for refrative materials we come from the transparent render path
- // but we do not want to do blending
- bool wasBlendingEnabled = theContext.IsBlendingEnabled();
- if (inMaterial.m_hasRefraction)
- theContext.SetBlendingEnabled(false);
-
- NVRenderContextScopedProperty<NVRenderFrameBuffer *> __framebuffer(
- theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget);
- NVRenderContextScopedProperty<NVRenderRect> __viewport(
- theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport);
-
- QT3DSVec2 theDestSize;
- bool theRenderTargetNeedsClear = false;
-
- NVConstDataRef<dynamic::SCommand *> theCommands(inClass.m_Class->GetRenderCommands());
- for (QT3DSU32 commandIdx = 0, commandEnd = theCommands.size(); commandIdx < commandEnd;
- ++commandIdx) {
- const SCommand &theCommand(*theCommands[commandIdx]);
-
- switch (theCommand.m_Type) {
- case CommandTypes::AllocateBuffer:
- AllocateBuffer(static_cast<const SAllocateBuffer &>(theCommand), inTarget);
- break;
- case CommandTypes::BindBuffer:
- theCurrentRenderTarget =
- BindBuffer(inMaterial, static_cast<const SBindBuffer &>(theCommand),
- theRenderTargetNeedsClear, theDestSize);
- break;
- case CommandTypes::BindTarget:
- // Restore the previous render target and info.
- theCurrentRenderTarget = inTarget;
- theContext.SetViewport(theOriginalViewport);
- break;
- case CommandTypes::BindShader: {
- theCurrentShader = NULL;
- SMaterialOrComputeShader theBindResult =
- BindShader(inRenderContext, inMaterial,
- static_cast<const SBindShader &>(theCommand), inFeatureSet);
- if (theBindResult.IsMaterialShader())
- theCurrentShader = &theBindResult.MaterialShader();
- } break;
- case CommandTypes::ApplyInstanceValue:
- // we apply the property update explicitly at the render pass
- break;
- case CommandTypes::Render:
- if (theCurrentShader) {
- RenderPass(inRenderContext, *theCurrentShader, theCurrentSourceTexture,
- theCurrentRenderTarget, theRenderTargetNeedsClear,
- *inRenderContext.m_Subset.m_InputAssembler,
- inRenderContext.m_Subset.m_Count, inRenderContext.m_Subset.m_Offset);
- }
- // reset
- theRenderTargetNeedsClear = false;
- break;
- case CommandTypes::ApplyBlending:
- ApplyBlending(static_cast<const SApplyBlending &>(theCommand));
- break;
- case CommandTypes::ApplyBufferValue:
- if (theCurrentShader)
- ApplyBufferValue(inMaterial, *theCurrentShader->m_Shader,
- static_cast<const SApplyBufferValue &>(theCommand),
- theCurrentSourceTexture);
- break;
- case CommandTypes::ApplyBlitFramebuffer:
- BlitFramebuffer(inRenderContext,
- static_cast<const SApplyBlitFramebuffer &>(theCommand), inTarget);
- break;
- default:
- QT3DS_ASSERT(false);
- break;
- }
- }
-
- if (inMaterial.m_hasRefraction)
- theContext.SetBlendingEnabled(wasBlendingEnabled);
-
- // Release any per-frame buffers
- for (QT3DSU32 idx = 0; idx < m_AllocatedBuffers.size(); ++idx) {
- if (m_AllocatedBuffers[idx].m_Flags.IsSceneLifetime() == false) {
- ReleaseBuffer(idx);
- --idx;
- }
- }
- }
-
- const char *GetShaderName(const SCustomMaterial &inMaterial) override
- {
- SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName);
- if (!theClass)
- return NULL;
-
- NVConstDataRef<dynamic::SCommand *> theCommands = theClass->m_Class->GetRenderCommands();
- TShaderAndFlags thePrepassShader;
- for (QT3DSU32 idx = 0, end = theCommands.size();
- idx < end && thePrepassShader.first.mPtr == NULL; ++idx) {
- const SCommand &theCommand = *theCommands[idx];
- if (theCommand.m_Type == CommandTypes::BindShader) {
- const SBindShader &theBindCommand = static_cast<const SBindShader &>(theCommand);
- return theBindCommand.m_ShaderPath.c_str();
- }
- }
-
- QT3DS_ASSERT(false);
- return NULL;
- }
-
- void ApplyShaderPropertyValues(const SCustomMaterial &inMaterial,
- NVRenderShaderProgram &inProgram) override
- {
- SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName);
- if (!theClass)
- return;
-
- SApplyInstanceValue applier;
- ApplyInstanceValue(const_cast<SCustomMaterial &>(inMaterial), *theClass, inProgram,
- applier);
- }
-
- void renderSubpresentations(SCustomMaterial &inMaterial) override
- {
- SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName);
- if (!theClass)
- return;
-
- NVConstDataRef<SPropertyDefinition> theDefs = theClass->m_Class->GetProperties();
- for (QT3DSU32 idx = 0, end = theDefs.size(); idx < end; ++idx) {
- const SPropertyDefinition &theDefinition(theDefs[idx]);
- if (theDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) {
- QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + theDefinition.m_Offset;
- StaticAssert<sizeof(CRegisteredString)
- == sizeof(NVRenderTexture2DPtr)>::valid_expression();
- CRegisteredString *theStrPtr = reinterpret_cast<CRegisteredString *>(dataPtr);
- IOffscreenRenderManager &theOffscreenRenderer(
- m_Context->GetOffscreenRenderManager());
-
- if (theStrPtr->IsValid()) {
- if (theOffscreenRenderer.HasOffscreenRenderer(*theStrPtr))
- theOffscreenRenderer.GetRenderedItem(*theStrPtr);
- }
- }
- }
- }
-
- virtual void PrepareTextureForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial)
- {
- NVConstDataRef<SPropertyDefinition> thePropDefs = inClass.m_Class->GetProperties();
- for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) {
- if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) {
- if (thePropDefs[idx].m_TexUsageType == NVRenderTextureTypeValue::Displace) {
- SImage *pImage = NULL;
-
- // we only do this to not miss if "None" is selected
- CRegisteredString theStrPtr = *reinterpret_cast<CRegisteredString *>(
- inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset);
-
- if (theStrPtr.IsValid()) {
-
- QT3DSU32 index = FindAllocatedImage(thePropDefs[idx].m_ImagePath);
- if (index == QT3DSU32(-1)) {
- pImage = QT3DS_NEW(m_CoreContext.GetAllocator(), SImage)();
- m_AllocatedImages.push_back(
- eastl::make_pair(thePropDefs[idx].m_ImagePath, pImage));
- } else
- pImage = m_AllocatedImages[index].second;
-
- if (inMaterial.m_DisplacementMap != pImage) {
- inMaterial.m_DisplacementMap = pImage;
- inMaterial.m_DisplacementMap->m_ImagePath =
- thePropDefs[idx].m_ImagePath;
- inMaterial.m_DisplacementMap->m_ImageShaderName =
- thePropDefs[idx].m_Name; // this is our name in the shader
- inMaterial.m_DisplacementMap->m_VerticalTilingMode =
- thePropDefs[idx].m_CoordOp;
- inMaterial.m_DisplacementMap->m_HorizontalTilingMode =
- thePropDefs[idx].m_CoordOp;
- }
- } else {
- inMaterial.m_DisplacementMap = NULL;
- }
- } else if (thePropDefs[idx].m_TexUsageType == NVRenderTextureTypeValue::Emissive2) {
- SImage *pImage = NULL;
-
- // we only do this to not miss if "None" is selected
- CRegisteredString theStrPtr = *reinterpret_cast<CRegisteredString *>(
- inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset);
-
- if (theStrPtr.IsValid()) {
- QT3DSU32 index = FindAllocatedImage(thePropDefs[idx].m_ImagePath);
- if (index == QT3DSU32(-1)) {
- pImage = QT3DS_NEW(m_CoreContext.GetAllocator(), SImage)();
- m_AllocatedImages.push_back(
- eastl::make_pair(thePropDefs[idx].m_ImagePath, pImage));
- } else
- pImage = m_AllocatedImages[index].second;
-
- if (inMaterial.m_EmissiveMap2 != pImage) {
- inMaterial.m_EmissiveMap2 = pImage;
- inMaterial.m_EmissiveMap2->m_ImagePath = thePropDefs[idx].m_ImagePath;
- inMaterial.m_EmissiveMap2->m_ImageShaderName =
- thePropDefs[idx].m_Name; // this is our name in the shader
- inMaterial.m_EmissiveMap2->m_VerticalTilingMode =
- thePropDefs[idx].m_CoordOp;
- inMaterial.m_EmissiveMap2->m_HorizontalTilingMode =
- thePropDefs[idx].m_CoordOp;
- }
- } else {
- inMaterial.m_EmissiveMap2 = NULL;
- }
- }
- }
- }
- }
-
- virtual void PrepareDisplacementForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial)
- {
- if (inMaterial.m_DisplacementMap == NULL)
- return;
-
- // our displacement mappin in MDL has fixed naming
- NVConstDataRef<SPropertyDefinition> thePropDefs = inClass.m_Class->GetProperties();
- for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) {
- if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSF32
- && AreEqual(thePropDefs[idx].m_Name.c_str(), "displaceAmount")) {
- QT3DSF32 theValue = *reinterpret_cast<const QT3DSF32 *>(inMaterial.GetDataSectionBegin()
- + thePropDefs[idx].m_Offset);
- inMaterial.m_DisplaceAmount = theValue;
- } else if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSVec3
- && AreEqual(thePropDefs[idx].m_Name.c_str(), "displace_tiling")) {
- QT3DSVec3 theValue = *reinterpret_cast<const QT3DSVec3 *>(inMaterial.GetDataSectionBegin()
- + thePropDefs[idx].m_Offset);
- if (theValue.x != inMaterial.m_DisplacementMap->m_Scale.x
- || theValue.y != inMaterial.m_DisplacementMap->m_Scale.y) {
- inMaterial.m_DisplacementMap->m_Scale = QT3DSVec2(theValue.x, theValue.y);
- inMaterial.m_DisplacementMap->m_Flags.SetTransformDirty(true);
- }
- }
- }
- }
-
- void PrepareMaterialForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial)
- {
- PrepareTextureForRender(inClass, inMaterial);
-
- if (inClass.m_HasDisplacement)
- PrepareDisplacementForRender(inClass, inMaterial);
- }
-
- // Returns true if the material is dirty and thus will produce a different render result
- // than previously. This effects things like progressive AA.
- // TODO - return more information, specifically about transparency (object is transparent,
- // object is completely transparent
- bool PrepareForRender(const SModel & /*inModel*/, const SRenderSubset & /*inSubset*/,
- SCustomMaterial &inMaterial, bool clearMaterialDirtyFlags) override
- {
- SMaterialClass *theMaterialClass = GetMaterialClass(inMaterial.m_ClassName);
- if (theMaterialClass == NULL) {
- QT3DS_ASSERT(false);
- return false;
- }
-
- PrepareMaterialForRender(*theMaterialClass, inMaterial);
-
- inMaterial.m_hasTransparency = theMaterialClass->m_HasTransparency;
- inMaterial.m_hasRefraction = theMaterialClass->m_HasRefraction;
- inMaterial.m_hasVolumetricDF = false;
-
- bool wasDirty = inMaterial.IsDirty() || theMaterialClass->m_AlwaysDirty;
- if (clearMaterialDirtyFlags)
- inMaterial.UpdateDirtyForFrame();
-
- return wasDirty;
- }
-
- // TODO - handle UIC specific features such as vertex offsets for prog-aa and opacity.
- void RenderSubset(SCustomMaterialRenderContext &inRenderContext,
- TShaderFeatureSet inFeatureSet) override
- {
- SMaterialClass *theClass = GetMaterialClass(inRenderContext.m_Material.m_ClassName);
-
- // Ensure that our overall render context comes back no matter what the client does.
- qt3ds::render::NVRenderContextScopedProperty<qt3ds::render::NVRenderBlendFunctionArgument>
- __blendFunction(m_Context->GetRenderContext(), &NVRenderContext::GetBlendFunction,
- &NVRenderContext::SetBlendFunction,
- qt3ds::render::NVRenderBlendFunctionArgument());
- qt3ds::render::NVRenderContextScopedProperty<qt3ds::render::NVRenderBlendEquationArgument>
- __blendEquation(m_Context->GetRenderContext(), &NVRenderContext::GetBlendEquation,
- &NVRenderContext::SetBlendEquation,
- qt3ds::render::NVRenderBlendEquationArgument());
-
- NVRenderContextScopedProperty<bool> theBlendEnabled(m_Context->GetRenderContext(),
- &NVRenderContext::IsBlendingEnabled,
- &NVRenderContext::SetBlendingEnabled);
-
- DoRenderCustomMaterial(inRenderContext, inRenderContext.m_Material, *theClass,
- m_Context->GetRenderContext().GetRenderTarget(), inFeatureSet);
- }
-
- bool RenderDepthPrepass(const QT3DSMat44 &inMVP, const SCustomMaterial &inMaterial,
- const SRenderSubset &inSubset) override
- {
- SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName);
- NVConstDataRef<dynamic::SCommand *> theCommands = theClass->m_Class->GetRenderCommands();
- TShaderAndFlags thePrepassShader;
- for (QT3DSU32 idx = 0, end = theCommands.size();
- idx < end && thePrepassShader.first.mPtr == NULL; ++idx) {
- const SCommand &theCommand = *theCommands[idx];
- if (theCommand.m_Type == CommandTypes::BindShader) {
- const SBindShader &theBindCommand = static_cast<const SBindShader &>(theCommand);
- thePrepassShader = m_Context->GetDynamicObjectSystem().GetDepthPrepassShader(
- theBindCommand.m_ShaderPath, CRegisteredString(), TShaderFeatureSet());
- }
- }
-
- if (thePrepassShader.first.mPtr == NULL)
- return false;
-
- NVRenderContext &theContext = m_Context->GetRenderContext();
- NVRenderShaderProgram &theProgram = *thePrepassShader.first;
- theContext.SetActiveShader(&theProgram);
- theProgram.SetPropertyValue("model_view_projection", inMVP);
- theContext.SetInputAssembler(inSubset.m_InputAssemblerPoints);
- theContext.Draw(NVRenderDrawMode::Lines, inSubset.m_PosVertexBuffer->GetNumVertexes(), 0);
- return true;
- }
-
- void OnMaterialActivationChange(const SCustomMaterial &inMaterial, bool inActive) override
- {
- Q_UNUSED(inMaterial)
- Q_UNUSED(inActive)
- }
-
- void EndFrame() override
- {
- QT3DSU64 currentFrameTime = qt3ds::foundation::Time::getCurrentTimeInTensOfNanoSeconds();
- if (m_LastFrameTime) {
- QT3DSU64 timePassed = currentFrameTime - m_LastFrameTime;
- m_MillisecondsSinceLastFrame = static_cast<QT3DSF32>(timePassed / 100000.0);
- }
- m_LastFrameTime = currentFrameTime;
- }
-
- void Save(qt3ds::render::SWriteBuffer &ioBuffer,
- const qt3ds::render::SStrRemapMap &inRemapMap,
- const char8_t * /*inProjectDir*/) const override
- {
- QT3DSU32 offset = ioBuffer.size();
- ioBuffer.write((QT3DSU32)m_StringMaterialMap.size());
- for (TStringMaterialMap::const_iterator iter = m_StringMaterialMap.begin(),
- end = m_StringMaterialMap.end();
- iter != end; ++iter) {
- size_t nameOffset = ioBuffer.size() - offset;
- (void)nameOffset;
- CRegisteredString materialName(iter->first);
- materialName.Remap(inRemapMap);
- ioBuffer.write(materialName);
- const SMaterialClass *materialClass = iter->second.mPtr;
- QT3DSU32 offset = ioBuffer.size();
- ioBuffer.write(*materialClass);
- QT3DSU8 *materialOffset = ioBuffer.begin() + offset;
- SMaterialClass *writtenClass = (SMaterialClass *)materialOffset;
- writtenClass->AfterWrite();
- ioBuffer.align(4);
- }
- }
-
- void Load(NVDataRef<QT3DSU8> inData, CStrTableOrDataRef inStrDataBlock,
- const char8_t * /*inProjectDir*/) override
- {
- m_Allocator.m_PreAllocatedBlock = inData;
- m_Allocator.m_OwnsMemory = false;
- qt3ds::render::SDataReader theReader(inData.begin(), inData.end());
- QT3DSU32 numMaterialClasses = theReader.LoadRef<QT3DSU32>();
- for (QT3DSU32 idx = 0; idx < numMaterialClasses; ++idx) {
- CRegisteredString clsName = theReader.LoadRef<CRegisteredString>();
- clsName.Remap(inStrDataBlock);
- IDynamicObjectClass *theDynamicCls =
- m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(clsName);
- SMaterialClass *theReadClass = theReader.Load<SMaterialClass>();
- theReader.Align(4);
- if (theDynamicCls) {
- theReadClass->AfterRead(m_Allocator, *theDynamicCls);
- m_StringMaterialMap.insert(eastl::make_pair(clsName, theReadClass));
- }
- }
- }
-
- ICustomMaterialSystem &GetCustomMaterialSystem(IQt3DSRenderContext &inContext) override
- {
- m_Context = &inContext;
-
- // check for fast blits
- NVRenderContext &theContext = m_Context->GetRenderContext();
- m_UseFastBlits = theContext.GetRenderBackendCap(
- qt3ds::render::NVRenderBackend::NVRenderBackendCaps::FastBlits);
-
- return *this;
- }
-};
-}
-
-ICustomMaterialSystemCore &
-ICustomMaterialSystemCore::CreateCustomMaterialSystemCore(IQt3DSRenderContextCore &ctx)
-{
- return *QT3DS_NEW(ctx.GetAllocator(), SMaterialSystem)(ctx);
-}
-