diff --git a/Engine/source/shaderGen/featureMgr.cpp b/Engine/source/shaderGen/featureMgr.cpp index 764804981..7e742bf58 100644 --- a/Engine/source/shaderGen/featureMgr.cpp +++ b/Engine/source/shaderGen/featureMgr.cpp @@ -96,16 +96,41 @@ ShaderFeature* FeatureMgr::getByType( const FeatureType &type ) return NULL; } -void FeatureMgr::registerFeature( const FeatureType &type, - ShaderFeature *feature ) +ShaderFeature* FeatureMgr::createFeature(const FeatureType& type, void* argStruct) { - // Remove any existing feature first. + FeatureInfoVector::iterator iter = mFeatures.begin(); + + for (; iter != mFeatures.end(); iter++) + { + if (*iter->type == type) + { + if (iter->createFunc != NULL) + { + return iter->createFunc(argStruct); + } + } + } + + return nullptr; +} + +void FeatureMgr::registerFeature( const FeatureType &type, + ShaderFeature *feature, + CreateShaderFeatureDelegate featureDelegate) +{ + if (feature == nullptr && featureDelegate == nullptr) + { + AssertFatal(false, "FeatureMgr::registerFeature - no feature or featureDelegate defined, cannot create this feature."); + } + + // Remove any existing feature. unregisterFeature( type ); // Now add the new feature. mFeatures.increment(); mFeatures.last().type = &type; mFeatures.last().feature = feature; + mFeatures.last().createFunc = featureDelegate; // Make sure we resort the features. mNeedsSort = true; diff --git a/Engine/source/shaderGen/featureMgr.h b/Engine/source/shaderGen/featureMgr.h index 4c897cf53..0b4eeecf1 100644 --- a/Engine/source/shaderGen/featureMgr.h +++ b/Engine/source/shaderGen/featureMgr.h @@ -27,16 +27,28 @@ #endif #ifndef _TVECTOR_H_ #include "core/util/tVector.h" -#endif +#endif + +#ifndef _UTIL_DELEGATE_H_ +#include "core/util/delegate.h" +#endif class FeatureType; class ShaderFeature; +typedef Delegate CreateShaderFeatureDelegate; + +/// /// Used by the feature manager. +/// +/// The shader feature type. +/// The shader feature class. +/// The static create function for this feature. struct FeatureInfo { const FeatureType *type; ShaderFeature *feature; + CreateShaderFeatureDelegate createFunc; }; @@ -67,10 +79,26 @@ public: /// ShaderFeature* getByType( const FeatureType &type ); - // Allows other systems to add features. index is - // the enum in GFXMaterialFeatureData. - void registerFeature( const FeatureType &type, - ShaderFeature *feature ); + /// + /// Creates a shader feature of this type with the arguments provided. + /// + /// The shader feature type. + /// The arguments for setting up this isntance of the shaderFeature. + /// An instance of the shader feature using its static createFunction taking in the + /// argument struct. + /// + ShaderFeature* createFeature(const FeatureType& type, void* argStruct); + + /// + /// Allows other systems to add features. index is + /// the enum in GFXMaterialFeatureData. + /// + /// The shader feature type. + /// The shader feature (can be null if featureDelegate defined) + /// The feature delegate create function. + void registerFeature(const FeatureType& type, + ShaderFeature* feature = nullptr, + CreateShaderFeatureDelegate featureDelegate = nullptr); // Unregister a feature. void unregisterFeature( const FeatureType &type ); @@ -86,4 +114,4 @@ public: // Helper for accessing the feature manager singleton. #define FEATUREMGR ManagedSingleton::instance() -#endif // FEATUREMGR \ No newline at end of file +#endif // FEATUREMGR diff --git a/Engine/source/shaderGen/featureSet.cpp b/Engine/source/shaderGen/featureSet.cpp index 2eff50e1c..f295536be 100644 --- a/Engine/source/shaderGen/featureSet.cpp +++ b/Engine/source/shaderGen/featureSet.cpp @@ -82,6 +82,14 @@ const FeatureType& FeatureSet::getAt( U32 index, S32 *outIndex ) const return *mFeatures[index].type; } +void* FeatureSet::getArguments(U32 index) const +{ + if (mFeatures[index].argStruct) + return mFeatures[index].argStruct; + + return nullptr; +} + void FeatureSet::clear() { mDescription.clear(); @@ -138,19 +146,23 @@ void FeatureSet::setFeature( const FeatureType &type, bool set, S32 index ) mDescription.clear(); } -void FeatureSet::addFeature( const FeatureType &type, S32 index ) +void FeatureSet::addFeature( const FeatureType &type, S32 index, void* argStruct ) { - for ( U32 i=0; i < mFeatures.size(); i++ ) + if (!argStruct) { - const FeatureInfo &info = mFeatures[i]; - if ( info.type == &type && - info.index == index ) - return; + for (U32 i = 0; i < mFeatures.size(); i++) + { + const FeatureInfo& info = mFeatures[i]; + if (info.type == &type && + info.index == index) + return; + } } FeatureInfo info; info.type = &type; info.index = index; + info.argStruct = argStruct; mFeatures.push_back( info ); mDescription.clear(); diff --git a/Engine/source/shaderGen/featureSet.h b/Engine/source/shaderGen/featureSet.h index 03b46f62a..b494492fd 100644 --- a/Engine/source/shaderGen/featureSet.h +++ b/Engine/source/shaderGen/featureSet.h @@ -42,6 +42,7 @@ protected: { const FeatureType* type; S32 index; + void* argStruct; }; /// The list of featurs. @@ -93,14 +94,21 @@ public: /// the feature index when it was added. const FeatureType& getAt( U32 index, S32 *outIndex = NULL ) const; + void* getArguments(U32 index) const; + /// Returns true if this handle has this feature. bool hasFeature( const FeatureType &type, S32 index = -1 ) const; /// void setFeature( const FeatureType &type, bool set, S32 index = -1 ); - /// - void addFeature( const FeatureType &type, S32 index = -1 ); + /// + /// Adds a feauter to the feature set. + /// + /// The shader feature type. + /// The inedx the shader feature will be sorted in the set. + /// A struct representing arguments for a shader feature. + void addFeature( const FeatureType &type, S32 index = -1, void* argStruct = nullptr ); /// void removeFeature( const FeatureType &type ); diff --git a/Engine/source/shaderGen/langElement.cpp b/Engine/source/shaderGen/langElement.cpp index cbf2d8406..461a6d43c 100644 --- a/Engine/source/shaderGen/langElement.cpp +++ b/Engine/source/shaderGen/langElement.cpp @@ -30,6 +30,69 @@ //************************************************************************** Vector LangElement::elementList( __FILE__, __LINE__ ); +const char* LangElement::constTypeToString(GFXShaderConstType constType) +{ + // Determine shader language based on GFXAdapterAPI + if (GFX->getAdapterType() == OpenGL) + { + switch (constType) + { + case GFXSCT_Float: return "float"; break; + case GFXSCT_Float2: return "vec2"; break; + case GFXSCT_Float3: return "vec3"; break; + case GFXSCT_Float4: return "vec4"; break; + case GFXSCT_Float2x2: return "mat2"; break; + case GFXSCT_Float3x3: return "mat3"; break; + case GFXSCT_Float3x4: return "mat3x4"; break; + case GFXSCT_Float4x3: return "mat4x3"; break; + case GFXSCT_Float4x4: return "mat4"; break; + case GFXSCT_Int: return "int"; break; + case GFXSCT_Int2: return "ivec2"; break; + case GFXSCT_Int3: return "ivec3"; break; + case GFXSCT_Int4: return "ivec4"; break; + case GFXSCT_UInt: return "uint"; break; + case GFXSCT_UInt2: return "uvec2"; break; + case GFXSCT_UInt3: return "uvec3"; break; + case GFXSCT_UInt4: return "uvec4"; break; + case GFXSCT_Bool: return "bool"; break; + case GFXSCT_Bool2: return "bvec2"; break; + case GFXSCT_Bool3: return "bvec3"; break; + case GFXSCT_Bool4: return "bvec4"; break; + default: return "unknown"; break; + } + } + else // Assume DirectX/HLSL + { + switch (constType) + { + case GFXSCT_Float: return "float"; break; + case GFXSCT_Float2: return "float2"; break; + case GFXSCT_Float3: return "float3"; break; + case GFXSCT_Float4: return "float4"; break; + case GFXSCT_Float2x2: return "float2x2"; break; + case GFXSCT_Float3x3: return "float3x3"; break; + case GFXSCT_Float3x4: return "float3x4"; break; + case GFXSCT_Float4x3: return "float4x3"; break; + case GFXSCT_Float4x4: return "float4x4"; break; + case GFXSCT_Int: return "int"; break; + case GFXSCT_Int2: return "int2"; break; + case GFXSCT_Int3: return "int3"; break; + case GFXSCT_Int4: return "int4"; break; + case GFXSCT_UInt: return "uint"; break; + case GFXSCT_UInt2: return "uint2"; break; + case GFXSCT_UInt3: return "uint3"; break; + case GFXSCT_UInt4: return "uint4"; break; + case GFXSCT_Bool: return "bool"; break; + case GFXSCT_Bool2: return "bool2"; break; + case GFXSCT_Bool3: return "bool3"; break; + case GFXSCT_Bool4: return "bool4"; break; + default: return "unknown"; break; + } + } + + return ""; +} + //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- @@ -121,6 +184,25 @@ Var::Var( const char *inName, const char *inType ) setType( inType ); } +Var::Var(const char* name, GFXShaderConstType type) +{ + structName[0] = '\0'; + connectName[0] = '\0'; + uniform = false; + vertData = false; + connector = false; + sampler = false; + texCoordNum = 0; + constSortPos = cspUninit; + constNum = 0; + arraySize = 1; + texture = false; + rank = 0; + + setName(name); + setType(type); +} + void Var::setUniform(const String& constType, const String& constName, ConstantSortPosition sortPos) { uniform = true; @@ -156,6 +238,14 @@ void Var::setType(const char *newType ) type[ sizeof( type ) - 1 ] = '\0'; } +void Var::setType(GFXShaderConstType constType) +{ + const char* typeStr = "unknown"; // Default unknown type + typeStr = constTypeToString(constType); + // Copy the string into type[] + dStrcpy((char*)type, typeStr, sizeof(type)); + type[sizeof(type) - 1] = '\0'; +} //-------------------------------------------------------------------------- // print //-------------------------------------------------------------------------- diff --git a/Engine/source/shaderGen/langElement.h b/Engine/source/shaderGen/langElement.h index 6608173e5..c6f25b77a 100644 --- a/Engine/source/shaderGen/langElement.h +++ b/Engine/source/shaderGen/langElement.h @@ -30,6 +30,10 @@ #include "core/stream/stream.h" #endif +#ifndef _GFXENUMS_H_ +#include "gfx/gfxEnums.h" +#endif + #define WRITESTR( a ){ stream.write( dStrlen(a), a ); } @@ -55,7 +59,7 @@ struct LangElement static void deleteElements(); U8 name[32]; - + static const char* constTypeToString(GFXShaderConstType constType); LangElement(); virtual ~LangElement() {}; virtual void print( Stream &stream ){}; @@ -131,10 +135,12 @@ struct Var : public LangElement // Default Var(); Var( const char *name, const char *type ); + Var( const char *name, GFXShaderConstType type ); void setStructName(const char *newName ); void setConnectName(const char *newName ); void setType(const char *newType ); + void setType(GFXShaderConstType constType); void print( Stream &stream ) override; diff --git a/Engine/source/shaderGen/shaderGen.cpp b/Engine/source/shaderGen/shaderGen.cpp index 3339aaea5..07781aea0 100644 --- a/Engine/source/shaderGen/shaderGen.cpp +++ b/Engine/source/shaderGen/shaderGen.cpp @@ -257,7 +257,13 @@ void ShaderGen::_processVertFeatures( Vector ¯os, bool macro { S32 index; const FeatureType &type = features.getAt( i, &index ); - ShaderFeature* feature = FEATUREMGR->getByType( type ); + void* args = features.getArguments(i); + ShaderFeature* feature = nullptr; + if(args) + feature = FEATUREMGR->createFeature(type, args); + else + feature = FEATUREMGR->getByType( type ); + if ( feature ) { feature->setProcessIndex( index ); @@ -300,7 +306,12 @@ void ShaderGen::_processPixFeatures( Vector ¯os, bool macros { S32 index; const FeatureType &type = features.getAt( i, &index ); - ShaderFeature* feature = FEATUREMGR->getByType( type ); + void* args = features.getArguments(i); + ShaderFeature* feature = nullptr; + if (args) + feature = FEATUREMGR->createFeature(type, args); + else + feature = FEATUREMGR->getByType(type); if ( feature ) { feature->setProcessIndex( index ); @@ -342,7 +353,12 @@ void ShaderGen::_printFeatureList(Stream &stream) { S32 index; const FeatureType &type = features.getAt( i, &index ); - ShaderFeature* feature = FEATUREMGR->getByType( type ); + void* args = features.getArguments(i); + ShaderFeature* feature = nullptr; + if (args) + feature = FEATUREMGR->createFeature(type, args); + else + feature = FEATUREMGR->getByType(type); if ( feature ) { String line; diff --git a/Engine/source/shaderGen/shaderOp.cpp b/Engine/source/shaderGen/shaderOp.cpp index c6597b94a..b160615aa 100644 --- a/Engine/source/shaderGen/shaderOp.cpp +++ b/Engine/source/shaderGen/shaderOp.cpp @@ -179,3 +179,19 @@ void GenOp::print( Stream &stream ) mElemList[i]->print( stream ); } } + +CastOp::CastOp(Var* in1, GFXShaderConstType type) : Parent(in1, NULL) +{ + mInput[0] = in1; + mConstType = constTypeToString(type); +} + +void CastOp::print(Stream& stream) +{ + Var* var = dynamic_cast(mInput[0]); + + WRITESTR(mConstType); + WRITESTR("( "); + mInput[0]->print(stream); + WRITESTR(" )"); +} diff --git a/Engine/source/shaderGen/shaderOp.h b/Engine/source/shaderGen/shaderOp.h index 63faad2ad..6b8966250 100644 --- a/Engine/source/shaderGen/shaderOp.h +++ b/Engine/source/shaderGen/shaderOp.h @@ -59,7 +59,6 @@ public: ShaderOp( LangElement *in1, LangElement *in2 ); }; -//---------------------------------------------------------------------------- /*! DecOp - Declaration Operation - Used when declaring a variable in a shader feature. It will automatically print the type of the variable and then @@ -82,7 +81,6 @@ public: float foo = 8.0 * 5.0; @endcode */ -//---------------------------------------------------------------------------- class DecOp : public ShaderOp { typedef ShaderOp Parent; @@ -163,4 +161,14 @@ public: }; +class CastOp : public ShaderOp +{ + typedef ShaderOp Parent; + const char* mConstType; +public: + CastOp(Var* in1, GFXShaderConstType type); + void print(Stream& stream) override; +}; + + #endif // _SHADEROP_H_