From 74138342d1e4fb2ea95e08eb67f664f274dfb69e Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 9 Oct 2017 17:15:57 -0500 Subject: [PATCH] Added support for uniforms, textures and samplers. --- .../shaderGen/HLSL/customFeatureHLSL.cpp | 128 +++++++++++++++++- .../source/shaderGen/HLSL/customFeatureHLSL.h | 39 ++++++ .../source/shaderGen/customShaderFeature.cpp | 30 ++++ Engine/source/shaderGen/customShaderFeature.h | 4 + Engine/source/shaderGen/langElement.cpp | 1 + Engine/source/shaderGen/shaderGen.cpp | 25 ++++ .../Full/game/art/shapes/cube/materials.cs | 17 ++- 7 files changed, 235 insertions(+), 9 deletions(-) diff --git a/Engine/source/shaderGen/HLSL/customFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/customFeatureHLSL.cpp index 98888f3e6..effe43468 100644 --- a/Engine/source/shaderGen/HLSL/customFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/customFeatureHLSL.cpp @@ -206,25 +206,104 @@ void CustomFeatureHLSL::setTexData(Material::StageData &stageDat, Con::executef(mOwner, "setTextureData"); } +void CustomFeatureHLSL::addUniform(String name, String type, String defaultValue, U32 arraySize) +{ + //do the var/arg fetching here + Var *newVar = (Var*)LangElement::find(name.c_str()); + if (!newVar) + { + VarHolder newVarHolder(name, type, ""); + newVarHolder.arraySize = arraySize; + newVarHolder.sampler = false; + newVarHolder.uniform = true; + newVarHolder.constSortPos = cspPrimitive; + + mVars.push_back(newVarHolder); + } +} + +void CustomFeatureHLSL::addSampler(String name, String type, U32 arraySize) +{ + //do the var/arg fetching here + Var *newVar = (Var*)LangElement::find(name.c_str()); + if (!newVar) + { + //As far as I know, it's always SamplerState regardless of the texture's type + VarHolder newVarHolder(name, "SamplerState", ""); + newVarHolder.arraySize = arraySize; + newVarHolder.sampler = true; + newVarHolder.uniform = true; + newVarHolder.constNum = Var::getTexUnitNum(); // used as texture unit num here + + mVars.push_back(newVarHolder); + } +} + +void CustomFeatureHLSL::addTexture(String name, String type, String samplerState, U32 arraySize) +{ + //do the var/arg fetching here + Var *newVar = (Var*)LangElement::find(name.c_str()); + if (!newVar) + { + //go find our sampler state var + U32 constNum = 0; + + Var *samplerStateVar = (Var*)LangElement::find(samplerState.c_str()); + if (!samplerStateVar) + { + //check our holder vars + bool foundHolder = false; + for (U32 v = 0; v < mVars.size(); v++) + { + if (mVars[v].varName == samplerState) + { + constNum = mVars[v].constNum; + foundHolder = true; + break; + } + } + + if (!foundHolder) + { + Con::errorf("CustomShaderFeature::addTexture: Unable to find texture's sampler state!"); + return; + } + } + else + { + constNum = samplerStateVar->constNum; + } + + VarHolder newVarHolder(name, type, ""); + newVarHolder.arraySize = arraySize; + newVarHolder.texture = true; + newVarHolder.uniform = true; + newVarHolder.constNum = constNum; // used as texture unit num here + + mVars.push_back(newVarHolder); + } +} + void CustomFeatureHLSL::addVariable(String name, String type, String defaultValue) { //do the var/arg fetching here Var *newVar = (Var*)LangElement::find(name.c_str()); if (!newVar) { - newVar = new Var(name, type); - LangElement *newVarDecl = new DecOp(newVar); - if (!defaultValue.isEmpty()) { char declareStatement[128]; dSprintf(declareStatement, 128, " @ = %s;\n", defaultValue.c_str()); + newVar = new Var(name, type); + LangElement *newVarDecl = new DecOp(newVar); meta->addStatement(new GenOp(declareStatement, newVarDecl)); } else { - meta->addStatement(new GenOp(" @;\n", newVarDecl)); + VarHolder newVarHolder(name, type, defaultValue); + + mVars.push_back(newVarHolder); } } } @@ -233,6 +312,7 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef *argv { //do the var/arg fetching here Vector varList; + bool declarationStatement = false; for (U32 i = 0; i < argc; i++) { @@ -240,9 +320,43 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef *argv Var *newVar = (Var*)LangElement::find(varName.c_str()); if (!newVar) { - //couldn't find that variable, bail out - Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue()); - return; + //ok, check our existing var holders, see if we just haven't utilized it yet + for (U32 v = 0; v < mVars.size(); v++) + { + if (mVars[v].varName == varName) + { + Var* newDeclVar = new Var(mVars[v].varName, mVars[v].type); + + newDeclVar->arraySize = mVars[v].arraySize; + newDeclVar->uniform = mVars[v].uniform; + newDeclVar->sampler = mVars[v].sampler; + newDeclVar->texture = mVars[v].texture; + newDeclVar->constNum = mVars[v].constNum; + newDeclVar->constSortPos = mVars[v].constSortPos; + + if (!newDeclVar->uniform) + { + LangElement *newVarDecl = new DecOp(newDeclVar); + newVar = (Var*)newVarDecl; + + declarationStatement = true; + } + else + { + newVar = newDeclVar; + } + + mVars.erase(v); + break; + } + } + + if (!newVar) + { + //couldn't find that variable, bail out + Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue()); + return; + } } varList.push_back(newVar); diff --git a/Engine/source/shaderGen/HLSL/customFeatureHLSL.h b/Engine/source/shaderGen/HLSL/customFeatureHLSL.h index 834f4f72a..d270242a1 100644 --- a/Engine/source/shaderGen/HLSL/customFeatureHLSL.h +++ b/Engine/source/shaderGen/HLSL/customFeatureHLSL.h @@ -27,6 +27,42 @@ class CustomFeatureHLSL : public ShaderFeatureHLSL { friend class CustomShaderFeatureData; + struct VarHolder + { + String varName; + String defaultValue; + String type; + bool uniform; + bool sampler; + bool texture; + U32 constNum; + ConstantSortPosition constSortPos; + U32 arraySize; + + VarHolder() : + varName(""), + type(""), + defaultValue(""), + uniform(false), + sampler(false), + texture(false), + constNum(0), + arraySize(0), + constSortPos(cspUninit) + { + } + + VarHolder(String _varName,String _type, String _defaultValue) : + uniform(false), sampler(false), texture(false), constNum(0), arraySize(0), constSortPos(cspUninit) + { + varName = _varName; + type = _type; + defaultValue = _defaultValue; + } + }; + + Vector mVars; + public: CustomShaderFeatureData* mOwner; @@ -64,6 +100,9 @@ public: return mOwner->getName(); } + void addUniform(String name, String type, String defaultValue, U32 arraySize = 0); void addVariable(String name, String type, String defaultValue); + void addSampler(String name, String type, U32 arraySize = 0); + void addTexture(String name, String type, String samplerState, U32 arraySize); void writeLine(String format, S32 argc, ConsoleValueRef *argv); }; \ No newline at end of file diff --git a/Engine/source/shaderGen/customShaderFeature.cpp b/Engine/source/shaderGen/customShaderFeature.cpp index 3f6f66c10..91f80b2db 100644 --- a/Engine/source/shaderGen/customShaderFeature.cpp +++ b/Engine/source/shaderGen/customShaderFeature.cpp @@ -89,6 +89,21 @@ void CustomShaderFeatureData::addVariable(String name, String type, String defau mFeatureHLSL->addVariable(name, type, defaultValue); } +void CustomShaderFeatureData::addUniform(String name, String type, String defaultValue, U32 arraySize) +{ + mFeatureHLSL->addUniform(name, type, defaultValue, arraySize); +} + +void CustomShaderFeatureData::addSampler(String name, String type, U32 arraySize) +{ + mFeatureHLSL->addSampler(name, type, arraySize); +} + +void CustomShaderFeatureData::addTexture(String name, String type, String samplerState, U32 arraySize) +{ + mFeatureHLSL->addTexture(name, type, samplerState, arraySize); +} + void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValueRef *argv) { /*mOnObject = onObject; @@ -136,6 +151,21 @@ DefineEngineMethod(CustomShaderFeatureData, addVariable, void, (String name, Str object->addVariable(name, type, defaultValue); } +DefineEngineMethod(CustomShaderFeatureData, addUniform, void, (String name, String type, String defaultValue, U32 arraySize), ("", "", "", 0), "") +{ + object->addUniform(name, type, defaultValue, arraySize); +} + +DefineEngineMethod(CustomShaderFeatureData, addSampler, void, (String name, U32 arraySize), ("", 0), "") +{ + object->addSampler(name, "", arraySize); +} + +DefineEngineMethod(CustomShaderFeatureData, addTexture, void, (String name, String type, String samplerState, U32 arraySize), ("", "", 0), "") +{ + object->addTexture(name, type, samplerState, arraySize); +} + ConsoleMethod(CustomShaderFeatureData, writeLine, void, 3, 0, "( string format, string args... ) Dynamically call a method on an object.\n" "@param method Name of method to call.\n" "@param args Zero or more arguments for the method.\n" diff --git a/Engine/source/shaderGen/customShaderFeature.h b/Engine/source/shaderGen/customShaderFeature.h index 312728df1..32b7d284d 100644 --- a/Engine/source/shaderGen/customShaderFeature.h +++ b/Engine/source/shaderGen/customShaderFeature.h @@ -59,6 +59,10 @@ public: //shadergen setup void addVariable(String name, String type, String defaultValue); + void addUniform(String name, String type, String defaultValue, U32 arraySize); + void addSampler(String name, String type, U32 arraySize); + void addTexture(String name, String type, String samplerState, U32 arraySize); + void writeLine(String format, S32 argc, ConsoleValueRef *argv); //shader generation diff --git a/Engine/source/shaderGen/langElement.cpp b/Engine/source/shaderGen/langElement.cpp index 59e9a3bde..57648e02c 100644 --- a/Engine/source/shaderGen/langElement.cpp +++ b/Engine/source/shaderGen/langElement.cpp @@ -112,6 +112,7 @@ Var::Var( const char *inName, const char *inType ) sampler = false; texCoordNum = 0; constSortPos = cspUninit; + constNum = 0; arraySize = 1; texture = false; rank = 0; diff --git a/Engine/source/shaderGen/shaderGen.cpp b/Engine/source/shaderGen/shaderGen.cpp index 5ed514aae..fc2e9d2b0 100644 --- a/Engine/source/shaderGen/shaderGen.cpp +++ b/Engine/source/shaderGen/shaderGen.cpp @@ -285,6 +285,31 @@ void ShaderGen::_processVertFeatures( Vector ¯os, bool macro } } + //Handle if we have any custom features + if (!mCustomFeaturesData.empty()) + { + for (U32 i = 0; i < mCustomFeaturesData.size(); ++i) + { + mCustomFeaturesData[i]->mFeatureHLSL->processVert(mComponents, mFeatureData); + + String line = String::ToString(" // %s\r\n", mCustomFeaturesData[i]->mFeatureHLSL->getName().c_str()); + mOutput->addStatement(new GenOp(line)); + + if (mCustomFeaturesData[i]->mFeatureHLSL->getOutput()) + mOutput->addStatement(mCustomFeaturesData[i]->mFeatureHLSL->getOutput()); + //ShaderFeatureHLSL feature = mCustomFeaturesData[i]->mHLSLFeature; + //feature->setProcessIndex(index); + + /*feature->processPixMacros(macros, mFeatureData); + + feature->setInstancingFormat(&mInstancingFormat); + feature->processPix(mComponents, mFeatureData);*/ + + mCustomFeaturesData[i]->mFeatureHLSL->reset(); + mOutput->addStatement(new GenOp(" \r\n")); + } + } + ShaderConnector *connect = dynamic_cast( mComponents[C_CONNECTOR] ); connect->sortVars(); } diff --git a/Templates/Full/game/art/shapes/cube/materials.cs b/Templates/Full/game/art/shapes/cube/materials.cs index 108e41ad7..345a7c4b8 100644 --- a/Templates/Full/game/art/shapes/cube/materials.cs +++ b/Templates/Full/game/art/shapes/cube/materials.cs @@ -50,19 +50,32 @@ singleton Material(cube_GridMaterial) mapTo = "GridMaterial"; CustomShaderFeature[0] = FlatColorFeature; + CustomShaderFeatureUniforms[FlatColorFeature,0] = "TestFloat"; }; //--- cube.dae MATERIALS END --- //Voodoo! -function FlatColorFeature::processVert(%this) +function FlatColorFeature::processVertHLSL(%this) { } function FlatColorFeature::processPixelHLSL(%this) { - %this.writeLine(" float bobsyeruncle = 15.915;"); + %this.addUniform("strudel", "float2"); + %this.addSampler("strudelMap"); + %this.addTexture("strudelTex", "Texture2D", "strudelMap"); + + %this.addVariable("bobsyeruncle", "float", 15.915); + %this.addVariable("chimmychanga", "float"); + + %this.writeLine(" @ = @ * 2;", "chimmychanga", "bobsyeruncle"); + %this.writeLine(" @ *= @.x;", "bobsyeruncle", "strudel"); + %this.writeLine(" @ *= @.y;", "chimmychanga", "strudel"); + + %this.addVariable("sprangle", "float4"); + %this.writeLine(" @ = @.Sample(@,@);", "sprangle", "strudelTex", "strudelMap", "strudel"); } function FlatColorFeature::setTextureResources(%this)