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:
marauder2k7 2025-11-08 20:14:51 +00:00
parent b919ab50ed
commit 7d3b4d8ac9
11 changed files with 650 additions and 12 deletions

View file

@ -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;

View file

@ -57,5 +57,6 @@ DefineConsoleType( TypeGFXTextureFilterType, GFXTextureFilterType );
DefineConsoleType( TypeGFXCullMode, GFXCullMode );
DefineConsoleType( TypeGFXStencilOp, GFXStencilOp );
DefineConsoleType( TypeGFXBlendOp, GFXBlendOp );
DefineConsoleType( TypeGFXShaderConstType, GFXShaderConstType);
#endif // !_GFXAPI_H_

View 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(&register_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;
}

View 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";
}
};

View file

@ -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)

View file

@ -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

View file

@ -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)
{

View file

@ -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 );

View file

@ -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
//--------------------------------------------------------------------------

View file

@ -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 ){};

View file

@ -257,7 +257,7 @@ void ShaderGen::_processVertFeatures( Vector<GFXShaderMacro> &macros, 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> &macros, 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);