mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-11 14:44:36 +00:00
shader nodes
Shader gen unification Shader node features can now be initialized with parameters set through FEATUREMGR This is to facilitate creation of node features from script. ShaderNode parameters are now no longer sent around as a void* and now use base type FeatureParamsBase
This commit is contained in:
parent
b919ab50ed
commit
7d3b4d8ac9
11 changed files with 650 additions and 12 deletions
|
|
@ -180,3 +180,37 @@ ImplementEnumType( GFXBlendOp,
|
|||
{ GFXBlendOpMax, "GFXBlendOpMax" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType(GFXShaderConstType,
|
||||
"The shader const types.\n"
|
||||
"@ingroup GFX")
|
||||
|
||||
{ GFXSCT_Uknown, "GFXSCT_Uknown" },
|
||||
{ GFXSCT_ConstBuffer, "GFXSCT_ConstBuffer" },
|
||||
{ GFXSCT_Float, "GFXSCT_Float" },
|
||||
{ GFXSCT_Float2, "GFXSCT_Float2" },
|
||||
{ GFXSCT_Float3, "GFXSCT_Float3" },
|
||||
{ GFXSCT_Float4, "GFXSCT_Float4" },
|
||||
{ GFXSCT_Float2x2, "GFXSCT_Float2x2" },
|
||||
{ GFXSCT_Float3x3, "GFXSCT_Float3x3" },
|
||||
{ GFXSCT_Float3x4, "GFXSCT_Float3x4" },
|
||||
{ GFXSCT_Float4x3, "GFXSCT_Float4x3" },
|
||||
{ GFXSCT_Float4x4, "GFXSCT_Float4x4" },
|
||||
{ GFXSCT_Int, "GFXSCT_Int" },
|
||||
{ GFXSCT_Int2, "GFXSCT_Int2" },
|
||||
{ GFXSCT_Int3, "GFXSCT_Int3" },
|
||||
{ GFXSCT_Int4, "GFXSCT_Int4" },
|
||||
{ GFXSCT_UInt, "GFXSCT_UInt" },
|
||||
{ GFXSCT_UInt2, "GFXSCT_UInt2" },
|
||||
{ GFXSCT_UInt3, "GFXSCT_UInt3" },
|
||||
{ GFXSCT_UInt4, "GFXSCT_UInt4" },
|
||||
{ GFXSCT_Bool, "GFXSCT_Bool" },
|
||||
{ GFXSCT_Bool2, "GFXSCT_Bool2" },
|
||||
{ GFXSCT_Bool3, "GFXSCT_Bool3" },
|
||||
{ GFXSCT_Bool4, "GFXSCT_Bool4" },
|
||||
{ GFXSCT_Sampler, "GFXSCT_Sampler" },
|
||||
{ GFXSCT_SamplerCube, "GFXSCT_SamplerCube" },
|
||||
{ GFXSCT_SamplerCubeArray, "GFXSCT_SamplerCubeArray" },
|
||||
{ GFXSCT_SamplerTextureArray, "GFXSCT_SamplerTextureArray" }
|
||||
|
||||
EndImplementEnumType;
|
||||
|
|
|
|||
|
|
@ -57,5 +57,6 @@ DefineConsoleType( TypeGFXTextureFilterType, GFXTextureFilterType );
|
|||
DefineConsoleType( TypeGFXCullMode, GFXCullMode );
|
||||
DefineConsoleType( TypeGFXStencilOp, GFXStencilOp );
|
||||
DefineConsoleType( TypeGFXBlendOp, GFXBlendOp );
|
||||
DefineConsoleType( TypeGFXShaderConstType, GFXShaderConstType);
|
||||
|
||||
#endif // !_GFXAPI_H_
|
||||
|
|
|
|||
302
Engine/source/shaderGen/NODE/shaderGenNodes.cpp
Normal file
302
Engine/source/shaderGen/NODE/shaderGenNodes.cpp
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
#include "platform/platform.h"
|
||||
#include "shaderGen/shaderGen.h"
|
||||
|
||||
#include "shaderGen/NODE/shaderGenNodes.h"
|
||||
#include "shaderGen/langElement.h"
|
||||
#include "shaderGen/shaderOp.h"
|
||||
#include "shaderGen/shaderGenVars.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "materials/matInstance.h"
|
||||
#include "materials/processedMaterial.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "core/util/autoPtr.h"
|
||||
|
||||
#include "core/module.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
|
||||
|
||||
ImplementFeatureType(SNF_DefaultTexCoord, U32(-1), -1, false);
|
||||
ImplementFeatureType(SNF_TextureFeature, U32(-1), -1, false);
|
||||
|
||||
ImplementEnumType(ShaderNodeFeature_enum, "Shader node features. Each of thes relates to a specific node for generating a shader.\n\n")
|
||||
{ ShaderNodeFeature_enum::eSNF_DefaultTexCoord, "SNF_DefaultTexCoord", "Setup the default texcoord." },
|
||||
{ ShaderNodeFeature_enum::eSNF_TextureFeature, "SNF_TextureFeature", "Sample a Texture - Params: (string,string,GFXSamplerStateData,bool)." },
|
||||
EndImplementEnumType;
|
||||
|
||||
namespace
|
||||
{
|
||||
void register_node_features(GFXAdapterType type)
|
||||
{
|
||||
FEATUREMGR->registerFeature(SNF_DefaultTexCoord, new DefaultTexcoordFeature);
|
||||
FEATUREMGR->registerFeature(SNF_TextureFeature, new TextureFeature, TextureFeature::createFunction);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MODULE_BEGIN(ShaderGenNodes)
|
||||
|
||||
MODULE_INIT_AFTER(ShaderGen)
|
||||
MODULE_INIT_AFTER(ShaderGenFeatureMgr)
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
SHADERGEN->getFeatureInitSignal().notify(®ister_node_features);
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
void ShaderFeatureNode::setupTextureSample( const String& samplerName,
|
||||
GFXShaderConstType samplerType,
|
||||
Vector<ShaderComponent*>& componentList,
|
||||
MultiLine* meta,
|
||||
LangElement* texCoord,
|
||||
LangElement* compareValue,
|
||||
bool useGather)
|
||||
{
|
||||
const bool isGL = (GFX->getAdapterType() == OpenGL);
|
||||
const bool isComparison = (compareValue != NULL);
|
||||
|
||||
// ---- Create or find texture/sampler vars ----
|
||||
String texVarName = samplerName + "_tex";
|
||||
String sampVarName = samplerName + "_sampler";
|
||||
|
||||
Var* textureVar = dynamic_cast<Var*>(LangElement::find(texVarName));
|
||||
Var* samplerVar = dynamic_cast<Var*>(LangElement::find(sampVarName));
|
||||
|
||||
if (!isGL)
|
||||
{
|
||||
// HLSL requires both Texture + SamplerState
|
||||
if (!samplerVar)
|
||||
{
|
||||
samplerVar = new Var;
|
||||
samplerVar->setType(isComparison ? "SamplerComparisonState" : "SamplerState");
|
||||
samplerVar->setName(sampVarName);
|
||||
samplerVar->uniform = true;
|
||||
samplerVar->sampler = true;
|
||||
samplerVar->constNum = Var::getTexUnitNum();
|
||||
}
|
||||
|
||||
if (!textureVar)
|
||||
{
|
||||
textureVar = new Var;
|
||||
textureVar->setType(LangElement::samplerTypeToString(samplerType)); // Texture2D, TextureCube, etc.
|
||||
textureVar->setName(texVarName);
|
||||
textureVar->uniform = true;
|
||||
textureVar->texture = true;
|
||||
textureVar->constNum = samplerVar->constNum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// GLSL uses a single sampler uniform
|
||||
if (!textureVar)
|
||||
{
|
||||
textureVar = new Var;
|
||||
textureVar->setType(LangElement::samplerTypeToString(samplerType));
|
||||
textureVar->setName(texVarName);
|
||||
textureVar->uniform = true;
|
||||
textureVar->sampler = true;
|
||||
textureVar->constNum = Var::getTexUnitNum();
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Emit sampling code ----
|
||||
String sampleFunc;
|
||||
if (isComparison)
|
||||
{
|
||||
if (useGather)
|
||||
sampleFunc = isGL ? "textureGather" : "SampleCmpGather";
|
||||
else
|
||||
sampleFunc = isGL ? "texture" : "SampleCmp";
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleFunc = isGL ? "texture" : "Sample";
|
||||
}
|
||||
|
||||
// The sampled color variable (e.g. "diffuseColor")
|
||||
Var* sampledColor = new Var;
|
||||
sampledColor->setType("float4");
|
||||
sampledColor->setName(samplerName); // The result var will be named like the sampler
|
||||
|
||||
if (isGL)
|
||||
{
|
||||
if (isComparison)
|
||||
{
|
||||
meta->addStatement(new GenOp(" @ = %s(@, @, @);\r\n",
|
||||
sampledColor, sampleFunc.c_str(), textureVar, texCoord, compareValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
meta->addStatement(new GenOp(" @ = %s(@, @);\r\n",
|
||||
sampledColor, sampleFunc.c_str(), textureVar, texCoord));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isComparison)
|
||||
{
|
||||
if (useGather)
|
||||
meta->addStatement(new GenOp(" @ = @.%s(@, @, @);\r\n",
|
||||
sampledColor, textureVar, sampleFunc.c_str(), samplerVar, texCoord, compareValue));
|
||||
else
|
||||
meta->addStatement(new GenOp(" @ = @.%s(@, @, @);\r\n",
|
||||
sampledColor, textureVar, sampleFunc.c_str(), samplerVar, texCoord, compareValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
meta->addStatement(new GenOp(" @ = @.%s(@, @);\r\n",
|
||||
sampledColor, textureVar, sampleFunc.c_str(), samplerVar, texCoord));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Var* ShaderFeatureNode::getOutTexCoord(const char* name, GFXShaderConstType type, bool useTexAnim, MultiLine* meta, Vector<ShaderComponent*>& componentList)
|
||||
{
|
||||
String outTexName = String::ToString("out_%s", name);
|
||||
Var* texCoord = (Var*)LangElement::find(outTexName);
|
||||
if (!texCoord)
|
||||
{
|
||||
Var* inTex = getVertTexCoord(name);
|
||||
AssertFatal(inTex, "ShaderFeatureNode::getOutTexCoord - Unknown vertex input coord!");
|
||||
|
||||
ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(componentList[C_CONNECTOR]);
|
||||
|
||||
texCoord = connectComp->getElement(RT_TEXCOORD);
|
||||
texCoord->setName(outTexName);
|
||||
texCoord->setStructName("OUT");
|
||||
texCoord->setType(type);
|
||||
|
||||
// Statement allows for casting of different types which
|
||||
// eliminates vector truncation problems.
|
||||
String statement = String::ToString(" @ = (%s)@;\r\n", type);
|
||||
meta->addStatement(new GenOp(statement, texCoord, inTex));
|
||||
|
||||
}
|
||||
|
||||
return texCoord;
|
||||
}
|
||||
|
||||
LangElement* ShaderFeatureNode::setupTexSpaceMat(Vector<ShaderComponent*>& componentList, Var** texSpaceMat)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LangElement* ShaderFeatureNode::assignColor(LangElement* elem, Material::BlendOp blend, LangElement* lerpElem, ShaderFeature::OutputTarget outputTarget)
|
||||
{
|
||||
// search for color var
|
||||
Var* color = (Var*)LangElement::find(getOutputTargetVarName(outputTarget));
|
||||
|
||||
if (!color)
|
||||
{
|
||||
// create color var
|
||||
color = new Var;
|
||||
color->setType("fragout");
|
||||
color->setName(getOutputTargetVarName(outputTarget));
|
||||
color->setStructName("OUT");
|
||||
|
||||
return new GenOp("@ = @", color, elem);
|
||||
}
|
||||
|
||||
switch (blend)
|
||||
{
|
||||
case Material::Add:
|
||||
return new GenOp("@ += @", color, elem);
|
||||
break;
|
||||
|
||||
case Material::Sub:
|
||||
return new GenOp("@ -= @", color, elem);
|
||||
break;
|
||||
|
||||
case Material::Mul:
|
||||
return new GenOp("@ *= @", color, elem);
|
||||
break;
|
||||
|
||||
case Material::PreMul:
|
||||
return new GenOp("@.rgb = @.rgb + (@.rgb*(1.0-@.a))", color, elem, color, elem);
|
||||
break;
|
||||
|
||||
case Material::AddAlpha:
|
||||
return new GenOp("@ += @ * @.a", color, elem, elem);
|
||||
break;
|
||||
|
||||
case Material::LerpAlpha:
|
||||
if (!lerpElem)
|
||||
lerpElem = elem;
|
||||
return new GenOp("@.rgb = lerp( @.rgb, (@).rgb, (@).a )", color, color, elem, lerpElem);
|
||||
break;
|
||||
|
||||
case Material::ToneMap:
|
||||
return new GenOp("@ = 1.0 - exp(-1.0 * @ * @)", color, color, elem);
|
||||
break;
|
||||
|
||||
case Material::None:
|
||||
return new GenOp("@ = @", color, elem);
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(false, "Unrecognized color blendOp");
|
||||
// Fallthru
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Setup the default texcoord
|
||||
//--------------------------------------------------------
|
||||
|
||||
void DefaultTexcoordFeature::processVert(Vector<ShaderComponent*>& componentList, const MaterialFeatureData& fd)
|
||||
{
|
||||
MultiLine* meta = new MultiLine;
|
||||
getOutTexCoord("texCoord",
|
||||
GFXSCT_Float2,
|
||||
fd.features[MFT_TexAnim],
|
||||
meta,
|
||||
componentList);
|
||||
output = meta;
|
||||
}
|
||||
|
||||
void DefaultTexcoordFeature::processPix(Vector<ShaderComponent*>& componentList, const MaterialFeatureData& fd)
|
||||
{
|
||||
// grab connector texcoord register
|
||||
Var* inTex = getInTexCoord("texCoord", GFXSCT_Float2, componentList);
|
||||
if (!inTex)
|
||||
return;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// TEXTURE SAMPLER FEATURE
|
||||
//--------------------------------------------------------
|
||||
|
||||
void TextureFeature::processPix(Vector<ShaderComponent*>& componentList, const MaterialFeatureData& fd)
|
||||
{
|
||||
// find the uv var.
|
||||
Var* inTex = (Var*)LangElement::find(params->uvName);
|
||||
if (!inTex)
|
||||
return;
|
||||
|
||||
MultiLine* meta = new MultiLine;
|
||||
|
||||
// Sample texture
|
||||
setupTextureSample(
|
||||
params->samplerName, // name of the output variable.
|
||||
params->samplerType, // or GFXSCT_SamplerCube, etc.
|
||||
componentList,
|
||||
meta,
|
||||
inTex,
|
||||
NULL, // compareValue (for SampleCmp)
|
||||
params->useGather // enable gather if desired
|
||||
);
|
||||
|
||||
output = meta;
|
||||
}
|
||||
|
||||
ShaderFeature::Resources TextureFeature::getResources(const MaterialFeatureData& fd)
|
||||
{
|
||||
Resources res;
|
||||
res.numTex = 1;
|
||||
res.numTexReg = 1;
|
||||
|
||||
return res;
|
||||
}
|
||||
140
Engine/source/shaderGen/NODE/shaderGenNodes.h
Normal file
140
Engine/source/shaderGen/NODE/shaderGenNodes.h
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef _SHADERFEATURE_H_
|
||||
#include "shaderGen/shaderFeature.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FEATUREMGR_H_
|
||||
#include "shaderGen/featureMgr.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FEATURETYPE_H_
|
||||
#include "shaderGen/featureType.h"
|
||||
#endif
|
||||
|
||||
#ifndef __GFXSTATEBLOCKDATA_H_
|
||||
#include "gfx/sim/gfxStateBlockData.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXAPI_H_
|
||||
#include "gfx/gfxAPI.h"
|
||||
#endif
|
||||
|
||||
DeclareFeatureType(SNF_DefaultTexCoord);
|
||||
DeclareFeatureType(SNF_TextureFeature);
|
||||
|
||||
/// <summary>
|
||||
/// This enum is so we can map to nodes in script.
|
||||
/// </summary>
|
||||
enum ShaderNodeFeature_enum
|
||||
{
|
||||
eSNF_DefaultTexCoord,
|
||||
eSNF_TextureFeature,
|
||||
};
|
||||
|
||||
DefineEnumType(ShaderNodeFeature_enum);
|
||||
|
||||
class ShaderFeatureNode : public ShaderFeature
|
||||
{
|
||||
public:
|
||||
void setupTextureSample(const String& samplerName,
|
||||
GFXShaderConstType samplerType,
|
||||
Vector<ShaderComponent*>& componentList,
|
||||
MultiLine* meta,
|
||||
LangElement* texCoord,
|
||||
LangElement* compareValue,
|
||||
bool useGather);
|
||||
|
||||
Var* getOutTexCoord( const char* name,
|
||||
GFXShaderConstType type,
|
||||
bool useTexAnim,
|
||||
MultiLine* meta,
|
||||
Vector<ShaderComponent*>& componentList);
|
||||
|
||||
LangElement* setupTexSpaceMat(Vector<ShaderComponent*>& componentList, Var** texSpaceMat) override;
|
||||
|
||||
LangElement* assignColor(LangElement* elem, Material::BlendOp blend, LangElement* lerpElem = NULL, ShaderFeature::OutputTarget outputTarget = ShaderFeature::DefaultTarget) override;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Parameters for the TextureFeature
|
||||
/// </summary>
|
||||
struct TextureFeatureParams : public FeatureParamsBase
|
||||
{
|
||||
String samplerName;
|
||||
GFXShaderConstType samplerType;
|
||||
GFXSamplerStateData samplerState;
|
||||
String uvName;
|
||||
bool useGather;
|
||||
|
||||
TextureFeatureParams()
|
||||
{
|
||||
samplerName = "defaultSampler";
|
||||
samplerType = GFXSCT_Sampler;
|
||||
uvName = "texCoord";
|
||||
useGather = false;
|
||||
|
||||
}
|
||||
|
||||
const char* getFeatureParamTypeName() const override { return "TextureFeatureParams"; }
|
||||
|
||||
static void persistedFields(Vector<FeatureParamField>& fields)
|
||||
{
|
||||
addParam(fields, "sampler", Offset(samplerName, TextureFeatureParams), TypeString);
|
||||
addParam(fields, "samplerType", Offset(samplerType, TextureFeatureParams), TypeGFXShaderConstType);
|
||||
addParam(fields, "samplerState", Offset(samplerState, TextureFeatureParams), TYPEID<GFXSamplerStateData>());
|
||||
addParam(fields, "uvName", Offset(uvName, TextureFeatureParams), TypeString);
|
||||
addParam(fields, "useGather", Offset(useGather, TextureFeatureParams), TypeBool);
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_FEATURE_PARAMS(SNF_TextureFeature, TextureFeatureParams)
|
||||
|
||||
class DefaultTexcoordFeature : public ShaderFeatureNode
|
||||
{
|
||||
void processVert(Vector<ShaderComponent*>& componentList,
|
||||
const MaterialFeatureData& fd) override;
|
||||
|
||||
void processPix(Vector<ShaderComponent*>& componentList,
|
||||
const MaterialFeatureData& fd) override;
|
||||
|
||||
String getName() override
|
||||
{
|
||||
return "Default TexCoord";
|
||||
}
|
||||
};
|
||||
|
||||
class TextureFeature : public ShaderFeatureNode
|
||||
{
|
||||
private:
|
||||
/// Parameters that this feature can use to change the shadergen output.
|
||||
TextureFeatureParams* params;
|
||||
public:
|
||||
/// default constructor
|
||||
TextureFeature()
|
||||
{
|
||||
params = new TextureFeatureParams();
|
||||
}
|
||||
/// Constructor that takes params as an argument
|
||||
TextureFeature(TextureFeatureParams* inParams)
|
||||
{
|
||||
params = inParams;
|
||||
}
|
||||
|
||||
void processPix(Vector<ShaderComponent*>& componentList,
|
||||
const MaterialFeatureData& fd) override;
|
||||
|
||||
ShaderFeature::Resources getResources(const MaterialFeatureData& fd);
|
||||
|
||||
// create a static function on the feature class
|
||||
static ShaderFeature* createFunction(FeatureParamsBase* args)
|
||||
{
|
||||
TextureFeatureParams* params = static_cast<TextureFeatureParams*>(args);
|
||||
return new TextureFeature(params);
|
||||
}
|
||||
|
||||
String getName() override
|
||||
{
|
||||
return "Texture Sampler";
|
||||
}
|
||||
};
|
||||
|
|
@ -51,6 +51,7 @@ FeatureMgr::FeatureMgr()
|
|||
: mNeedsSort( false )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mFeatures );
|
||||
VECTOR_SET_ASSOCIATION( mParamInfos );
|
||||
}
|
||||
|
||||
FeatureMgr::~FeatureMgr()
|
||||
|
|
@ -96,7 +97,7 @@ ShaderFeature* FeatureMgr::getByType( const FeatureType &type )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ShaderFeature* FeatureMgr::createFeature(const FeatureType& type, void* argStruct)
|
||||
ShaderFeature* FeatureMgr::createFeature(const FeatureType& type, FeatureParamsBase* argStruct)
|
||||
{
|
||||
FeatureInfoVector::iterator iter = mFeatures.begin();
|
||||
|
||||
|
|
@ -114,6 +115,64 @@ ShaderFeature* FeatureMgr::createFeature(const FeatureType& type, void* argStruc
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void FeatureMgr::registerFeatureParams(const FeatureType& type, const FeatureParamField* fields, U32 fieldCount, CreateFeatureParams createFn)
|
||||
{
|
||||
// Replace if already exists
|
||||
for (U32 i = 0; i < mParamInfos.size(); ++i)
|
||||
{
|
||||
if (*mParamInfos[i].type == type)
|
||||
{
|
||||
mParamInfos.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mParamInfos.increment();
|
||||
mParamInfos.last().type = &type;
|
||||
mParamInfos.last().fields = fields;
|
||||
mParamInfos.last().fieldCount = fieldCount;
|
||||
mParamInfos.last().createFn = createFn;
|
||||
|
||||
}
|
||||
|
||||
FeatureParamsBase* FeatureMgr::createFeatureParams(const FeatureType& type) const
|
||||
{
|
||||
for (U32 i = 0; i < mParamInfos.size(); ++i)
|
||||
{
|
||||
if (*mParamInfos[i].type == type)
|
||||
return mParamInfos[i].createFn();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FeatureMgr::applyFeatureParams(const FeatureType& type,
|
||||
FeatureParamsBase* params,
|
||||
const Vector<String>& args) const
|
||||
{
|
||||
const FeatureParamInfo* info = nullptr;
|
||||
for (U32 i = 0; i < mParamInfos.size(); ++i)
|
||||
{
|
||||
if (*mParamInfos[i].type == type)
|
||||
{
|
||||
info = &mParamInfos[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!info || !params)
|
||||
return;
|
||||
|
||||
for (U32 i = 0; i < info->fieldCount; ++i)
|
||||
{
|
||||
const FeatureParamField& f = info->fields[i];
|
||||
const char* val = args[i].c_str();
|
||||
|
||||
void* fieldPtr = (U8*)params + f.offset;
|
||||
// no array support yet.
|
||||
Con::setData(f.type, fieldPtr, 0, 1, &val);
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureMgr::registerFeature( const FeatureType &type,
|
||||
ShaderFeature *feature,
|
||||
CreateShaderFeatureDelegate featureDelegate)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,48 @@
|
|||
class FeatureType;
|
||||
class ShaderFeature;
|
||||
|
||||
typedef Delegate<ShaderFeature* (void*)> CreateShaderFeatureDelegate;
|
||||
struct FeatureParamField
|
||||
{
|
||||
StringTableEntry paramName;
|
||||
S32 offset;
|
||||
S32 type;
|
||||
U32 arraySize;
|
||||
};
|
||||
|
||||
inline void addParam(Vector<FeatureParamField>& list,
|
||||
const char* name,
|
||||
S32 offset,
|
||||
S32 consoleType,
|
||||
U32 arraySize = 1)
|
||||
{
|
||||
FeatureParamField f = { name, offset, consoleType, arraySize };
|
||||
list.push_back(f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all shader feature parameter structs.
|
||||
/// </summary>
|
||||
class FeatureParamsBase
|
||||
{
|
||||
public:
|
||||
virtual ~FeatureParamsBase() {}
|
||||
|
||||
// For debug or script reflection, you can override to serialize/print parameters
|
||||
virtual const char* getFeatureParamTypeName() const { return "FeatureParamsBase"; }
|
||||
};
|
||||
|
||||
typedef Delegate<FeatureParamsBase* ()> CreateFeatureParams;
|
||||
|
||||
/// Metadata for a parameter struct type.
|
||||
struct FeatureParamInfo
|
||||
{
|
||||
const FeatureType* type; // Matches feature
|
||||
const FeatureParamField* fields;
|
||||
U32 fieldCount;
|
||||
CreateFeatureParams createFn; // makes a new param struct
|
||||
};
|
||||
|
||||
typedef Delegate<ShaderFeature* (FeatureParamsBase*)> CreateShaderFeatureDelegate;
|
||||
|
||||
/// <summary>
|
||||
/// Used by the feature manager.
|
||||
|
|
@ -60,9 +101,11 @@ protected:
|
|||
bool mNeedsSort;
|
||||
|
||||
typedef Vector<FeatureInfo> FeatureInfoVector;
|
||||
|
||||
FeatureInfoVector mFeatures;
|
||||
|
||||
typedef Vector<FeatureParamInfo> FeatureParamInfoVector;
|
||||
FeatureParamInfoVector mParamInfos;
|
||||
|
||||
static S32 QSORT_CALLBACK _featureInfoCompare( const FeatureInfo *a, const FeatureInfo *b );
|
||||
|
||||
public:
|
||||
|
|
@ -87,7 +130,13 @@ public:
|
|||
/// <returns>An instance of the shader feature using its static createFunction taking in the
|
||||
/// argument struct.
|
||||
/// </returns>
|
||||
ShaderFeature* createFeature(const FeatureType& type, void* argStruct);
|
||||
ShaderFeature* createFeature(const FeatureType& type, FeatureParamsBase* argStruct);
|
||||
|
||||
void registerFeatureParams(const FeatureType& type, const FeatureParamField* fields, U32 fieldCount, CreateFeatureParams createFn);
|
||||
|
||||
FeatureParamsBase* createFeatureParams(const FeatureType& type) const;
|
||||
|
||||
void applyFeatureParams(const FeatureType& type, FeatureParamsBase* params, const Vector<String>& args) const;
|
||||
|
||||
/// <summary>
|
||||
/// Allows other systems to add features. index is
|
||||
|
|
@ -114,4 +163,20 @@ public:
|
|||
// Helper for accessing the feature manager singleton.
|
||||
#define FEATUREMGR ManagedSingleton<FeatureMgr>::instance()
|
||||
|
||||
#define REGISTER_FEATURE_PARAMS(TYPE, STRUCT_TYPE) \
|
||||
struct STRUCT_TYPE##_AutoRegister \
|
||||
{ \
|
||||
STRUCT_TYPE##_AutoRegister() \
|
||||
{ \
|
||||
Vector<FeatureParamField> fieldList; \
|
||||
STRUCT_TYPE::persistedFields(fieldList); \
|
||||
FEATUREMGR->registerFeatureParams( \
|
||||
TYPE, \
|
||||
fieldList.address(), \
|
||||
fieldList.size(), \
|
||||
Delegate<FeatureParamsBase*()>([]() -> FeatureParamsBase* { return new STRUCT_TYPE(); })\
|
||||
); \
|
||||
} \
|
||||
} STRUCT_TYPE##_AutoRegisterInstance;
|
||||
|
||||
#endif // FEATUREMGR
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ const FeatureType& FeatureSet::getAt( U32 index, S32 *outIndex ) const
|
|||
return *mFeatures[index].type;
|
||||
}
|
||||
|
||||
void* FeatureSet::getArguments(U32 index) const
|
||||
FeatureParamsBase* FeatureSet::getArguments(U32 index) const
|
||||
{
|
||||
if (mFeatures[index].argStruct)
|
||||
return mFeatures[index].argStruct;
|
||||
|
|
@ -146,7 +146,7 @@ void FeatureSet::setFeature( const FeatureType &type, bool set, S32 index )
|
|||
mDescription.clear();
|
||||
}
|
||||
|
||||
void FeatureSet::addFeature( const FeatureType &type, S32 index, void* argStruct )
|
||||
void FeatureSet::addFeature( const FeatureType &type, S32 index, FeatureParamsBase* argStruct )
|
||||
{
|
||||
if (!argStruct)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@
|
|||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _FEATUREMGR_H_
|
||||
#include "shaderGen/featureMgr.h"
|
||||
#endif
|
||||
|
||||
class FeatureType;
|
||||
|
||||
|
|
@ -42,7 +45,7 @@ protected:
|
|||
{
|
||||
const FeatureType* type;
|
||||
S32 index;
|
||||
void* argStruct;
|
||||
FeatureParamsBase* argStruct;
|
||||
};
|
||||
|
||||
/// The list of featurs.
|
||||
|
|
@ -94,7 +97,7 @@ public:
|
|||
/// the feature index when it was added.
|
||||
const FeatureType& getAt( U32 index, S32 *outIndex = NULL ) const;
|
||||
|
||||
void* getArguments(U32 index) const;
|
||||
FeatureParamsBase* getArguments(U32 index) const;
|
||||
|
||||
/// Returns true if this handle has this feature.
|
||||
bool hasFeature( const FeatureType &type, S32 index = -1 ) const;
|
||||
|
|
@ -108,7 +111,7 @@ public:
|
|||
/// <param name="type">The shader feature type.</param>
|
||||
/// <param name="index">The inedx the shader feature will be sorted in the set.</param>
|
||||
/// <param name="argStruct">A struct representing arguments for a shader feature.</param>
|
||||
void addFeature( const FeatureType &type, S32 index = -1, void* argStruct = nullptr );
|
||||
void addFeature( const FeatureType &type, S32 index = -1, FeatureParamsBase* argStruct = nullptr );
|
||||
|
||||
///
|
||||
void removeFeature( const FeatureType &type );
|
||||
|
|
|
|||
|
|
@ -93,6 +93,39 @@ const char* LangElement::constTypeToString(GFXShaderConstType constType)
|
|||
return "";
|
||||
}
|
||||
|
||||
const char* LangElement::samplerTypeToString(GFXShaderConstType constType)
|
||||
{
|
||||
if (constType < GFXSCT_Sampler)
|
||||
return "";
|
||||
|
||||
// Determine shader language based on GFXAdapterAPI
|
||||
if (GFX->getAdapterType() == OpenGL)
|
||||
{
|
||||
switch (constType)
|
||||
{
|
||||
case GFXSCT_Sampler: return "sampler2D"; break;
|
||||
case GFXSCT_SamplerCube: return "samplerCube"; break;
|
||||
case GFXSCT_SamplerTextureArray: return "sampler2DArray"; break;
|
||||
case GFXSCT_SamplerCubeArray: return "samplerCubeArray"; break;
|
||||
default: return "unknown"; break;
|
||||
}
|
||||
}
|
||||
else // Assume DirectX/HLSL
|
||||
{
|
||||
switch (constType)
|
||||
{
|
||||
case GFXSCT_Sampler: return "Texture2D"; break;
|
||||
case GFXSCT_SamplerCube: return "TextureCube"; break;
|
||||
case GFXSCT_SamplerTextureArray: return "Texture2DArray"; break;
|
||||
case GFXSCT_SamplerCubeArray: return "TextureCubeArray"; break;
|
||||
default: return "unknown"; break;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct LangElement
|
|||
|
||||
U8 name[32];
|
||||
static const char* constTypeToString(GFXShaderConstType constType);
|
||||
static const char* samplerTypeToString(GFXShaderConstType constType);
|
||||
LangElement();
|
||||
virtual ~LangElement() {};
|
||||
virtual void print( Stream &stream ){};
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ void ShaderGen::_processVertFeatures( Vector<GFXShaderMacro> ¯os, bool macro
|
|||
{
|
||||
S32 index;
|
||||
const FeatureType &type = features.getAt( i, &index );
|
||||
void* args = features.getArguments(i);
|
||||
FeatureParamsBase* args = features.getArguments(i);
|
||||
ShaderFeature* feature = nullptr;
|
||||
if(args)
|
||||
feature = FEATUREMGR->createFeature(type, args);
|
||||
|
|
@ -306,7 +306,7 @@ void ShaderGen::_processPixFeatures( Vector<GFXShaderMacro> ¯os, bool macros
|
|||
{
|
||||
S32 index;
|
||||
const FeatureType &type = features.getAt( i, &index );
|
||||
void* args = features.getArguments(i);
|
||||
FeatureParamsBase* args = features.getArguments(i);
|
||||
ShaderFeature* feature = nullptr;
|
||||
if (args)
|
||||
feature = FEATUREMGR->createFeature(type, args);
|
||||
|
|
@ -353,7 +353,7 @@ void ShaderGen::_printFeatureList(Stream &stream)
|
|||
{
|
||||
S32 index;
|
||||
const FeatureType &type = features.getAt( i, &index );
|
||||
void* args = features.getArguments(i);
|
||||
FeatureParamsBase* args = features.getArguments(i);
|
||||
ShaderFeature* feature = nullptr;
|
||||
if (args)
|
||||
feature = FEATUREMGR->createFeature(type, args);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue