Sfoglia il codice sorgente

Changes for get necesary sampler names for OpenGL shaders.

LuisAntonRebollo 11 anni fa
parent
commit
1ac8fab884

+ 4 - 1
Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp

@@ -98,7 +98,7 @@ void DeferredRTLightingFeatHLSL::processPix( Vector<ShaderComponent*> &component
    uvScene->setName( "uvScene" );
    LangElement *uvSceneDecl = new DecOp( uvScene );
 
-   String rtParamName = String::ToString( "rtParams%d", mLastTexIndex );
+   String rtParamName = String::ToString( "rtParams%s", "lightInfoBuffer" );
    Var *rtParams = (Var*) LangElement::find( rtParamName );
    if( !rtParams )
    {
@@ -207,6 +207,7 @@ void DeferredRTLightingFeatHLSL::setTexData( Material::StageData &stageDat,
       mLastTexIndex = texIndex;
 
       passData.mTexType[ texIndex ] = Material::TexTarget;
+      passData.mSamplerNames[ texIndex ]= "lightInfoBuffer";
       passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
    }
 }
@@ -402,12 +403,14 @@ void DeferredBumpFeatHLSL::setTexData( Material::StageData &stageDat,
            fd.features[MFT_PixSpecular] ) )
    {
       passData.mTexType[ texIndex ] = Material::Bump;
+      passData.mSamplerNames[ texIndex ] = "bumpMap";
       passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
 
       if (  fd.features[MFT_PrePassConditioner] &&
             fd.features.hasFeature( MFT_DetailNormalMap ) )
       {
          passData.mTexType[ texIndex ] = Material::DetailBump;
+         passData.mSamplerNames[ texIndex ] = "detailBumpMap";
          passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
       }
    }

+ 16 - 3
Engine/source/materials/customMaterialDefinition.cpp

@@ -138,9 +138,22 @@ bool CustomMaterial::onAdd()
             return false;
          }
          
-      	mSamplerNames[i] = entry->slotName + dStrlen(samplerDecl);
-         mSamplerNames[i].insert(0, '$');
-         mTexFilename[i] = entry->value;
+         // Assert sampler names are defined on ShaderData
+         S32 pos = -1;
+         String samplerName = entry->slotName + dStrlen(samplerDecl);
+         samplerName.insert(0, '$');
+         mShaderData->hasSamplerDef(samplerName, pos);
+         
+         if(pos == -1)
+         {
+            const char *error = (avar("CustomMaterial(%s) bind sampler[%s] and is not present on ShaderData(%s)", 
+               getName(), samplerName.c_str(), mShaderDataName.c_str() ));
+            Con::errorf(error);
+            GFXAssertFatal(0, error);
+            continue;
+         }
+         mSamplerNames[pos] = samplerName;
+         mTexFilename[pos] = entry->value;
          ++i;
       }
    }

+ 26 - 2
Engine/source/materials/processedCustomMaterial.cpp

@@ -79,6 +79,7 @@ void ProcessedCustomMaterial::_setStageData()
       if(filename.equal(String("$dynamiclight"), String::NoCase))
       {
          rpd->mTexType[i] = Material::DynamicLight;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -86,6 +87,7 @@ void ProcessedCustomMaterial::_setStageData()
       if(filename.equal(String("$dynamiclightmask"), String::NoCase))
       {
          rpd->mTexType[i] = Material::DynamicLightMask;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -93,6 +95,7 @@ void ProcessedCustomMaterial::_setStageData()
       if(filename.equal(String("$lightmap"), String::NoCase))
       {
          rpd->mTexType[i] = Material::Lightmap;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -102,6 +105,7 @@ void ProcessedCustomMaterial::_setStageData()
          if( mCustomMaterial->mCubemapData )
          {
             rpd->mTexType[i] = Material::Cube;
+            rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
             mMaxTex = i+1;
          }
          else
@@ -114,6 +118,7 @@ void ProcessedCustomMaterial::_setStageData()
       if(filename.equal(String("$dynamicCubemap"), String::NoCase))
       {
          rpd->mTexType[i] = Material::SGCube;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -121,6 +126,7 @@ void ProcessedCustomMaterial::_setStageData()
       if(filename.equal(String("$backbuff"), String::NoCase))
       {
          rpd->mTexType[i] = Material::BackBuff;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -128,6 +134,7 @@ void ProcessedCustomMaterial::_setStageData()
       if(filename.equal(String("$reflectbuff"), String::NoCase))
       {
          rpd->mTexType[i] = Material::ReflectBuff;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -135,6 +142,7 @@ void ProcessedCustomMaterial::_setStageData()
       if(filename.equal(String("$miscbuff"), String::NoCase))
       {
          rpd->mTexType[i] = Material::Misc;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -151,6 +159,7 @@ void ProcessedCustomMaterial::_setStageData()
             texTarget->getShaderMacros( &mConditionerMacros );
 
          rpd->mTexType[i] = Material::TexTarget;
+         rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
          mMaxTex = i+1;
          continue;
       }
@@ -162,6 +171,7 @@ void ProcessedCustomMaterial::_setStageData()
          continue;
       }
       rpd->mTexType[i] = Material::Standard;
+      rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
       mMaxTex = i+1;
    }
 
@@ -232,6 +242,20 @@ bool ProcessedCustomMaterial::init( const FeatureSet &features,
    setMaterialParameters( mDefaultParameters, 0 );
    mStateHint.init( this );
    
+   for(int i = 0; i < mMaxTex; i++)
+   {
+      ShaderConstHandles *handles = _getShaderConstHandles( mPasses.size()-1 );
+      AssertFatal(handles,"");
+
+      if(rpd->mSamplerNames[i].isEmpty())      
+         continue;      
+
+      String samplerName = rpd->mSamplerNames[i].startsWith("$") ? rpd->mSamplerNames[i] : String("$") + rpd->mSamplerNames[i];
+      GFXShaderConstHandle *handle = rpd->shader->getShaderConstHandle( samplerName ); 
+      AssertFatal(handle,"");
+      handles->mTexHandlesSC[i] = handle;
+   }
+   
    return true;
 }
 
@@ -384,14 +408,14 @@ void ProcessedCustomMaterial::setTextureStages( SceneRenderState *state, const S
                if ( !texObject )
                   texObject = GFXTexHandle::ZERO;
 
-               if ( handles->mRTParamsSC[samplerRegister]->isValid() && texObject )
+               if ( handles->mRTParamsSC[i]->isValid() && texObject )
                {
                   const Point3I &targetSz = texObject->getSize();
                   const RectI &targetVp = texTarget->getViewport();
                   Point4F rtParams;
 
                   ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);
-                  shaderConsts->set(handles->mRTParamsSC[samplerRegister], rtParams);
+                  shaderConsts->set(handles->mRTParamsSC[i], rtParams);
                }
               
                GFX->setTexture( samplerRegister, texObject );

+ 56 - 1
Engine/source/materials/processedShaderMaterial.cpp

@@ -221,6 +221,7 @@ bool ProcessedShaderMaterial::init( const FeatureSet &features,
          {
             rpd->mTexSlot[0].texTarget = texTarget;
             rpd->mTexType[0] = Material::TexTarget;
+            rpd->mSamplerNames[0] = "diffuseMap";
          }
       }
 
@@ -516,8 +517,23 @@ bool ProcessedShaderMaterial::_createPasses( MaterialFeatureData &stageFeatures,
 
       passData.mNumTexReg += numTexReg;
       passData.mFeatureData.features.addFeature( *info.type );
+
+#if defined(TORQUE_DEBUG) && defined( TORQUE_OPENGL)
+      U32 oldTexNumber = texIndex;
+#endif
+
       info.feature->setTexData( mStages[stageNum], stageFeatures, passData, texIndex );
 
+#if defined(TORQUE_DEBUG) && defined( TORQUE_OPENGL)
+      if(oldTexNumber != texIndex)
+      {
+         for(int i = oldTexNumber; i < texIndex; i++)
+         {
+            AssertFatal(passData.mSamplerNames[ oldTexNumber ].isNotEmpty(), avar( "ERROR: ShaderGen feature %s don't set used sampler name", info.feature->getName().c_str()) );
+         }
+      }
+#endif
+
       // Add pass if tex units are maxed out
       if( texIndex > GFX->getNumSamplers() )
       {
@@ -527,6 +543,13 @@ bool ProcessedShaderMaterial::_createPasses( MaterialFeatureData &stageFeatures,
       }
    }
 
+#if defined(TORQUE_DEBUG) && defined( TORQUE_OPENGL)
+   for(int i = 0; i < texIndex; i++)
+   {
+      AssertFatal(passData.mSamplerNames[ i ].isNotEmpty(),"");
+   }
+#endif
+
    const FeatureSet &passFeatures = passData.mFeatureData.codify();
    if ( passFeatures.isNotEmpty() )
    {
@@ -587,9 +610,16 @@ bool ProcessedShaderMaterial::_addPass( ShaderRenderPassData &rpd,
    // Copy over features
    rpd.mFeatureData.materialFeatures = fd.features;
 
+   Vector<String> samplers;
+   samplers.setSize(Material::MAX_TEX_PER_PASS);
+   for(int i = 0; i < Material::MAX_TEX_PER_PASS; ++i)
+   {
+      samplers[i] = (rpd.mSamplerNames[i].isEmpty() || rpd.mSamplerNames[i][0] == '$') ? rpd.mSamplerNames[i] : "$" + rpd.mSamplerNames[i];
+   }
+
    // Generate shader
    GFXShader::setLogging( true, true );
-   rpd.shader = SHADERGEN->getShader( rpd.mFeatureData, mVertexFormat, &mUserMacros );
+   rpd.shader = SHADERGEN->getShader( rpd.mFeatureData, mVertexFormat, &mUserMacros, samplers );
    if( !rpd.shader )
       return false;
    rpd.shaderHandles.init( rpd.shader );   
@@ -601,6 +631,30 @@ bool ProcessedShaderMaterial::_addPass( ShaderRenderPassData &rpd,
    ShaderRenderPassData *newPass = new ShaderRenderPassData( rpd );
    mPasses.push_back( newPass );
 
+   //initSamplerHandles
+   ShaderConstHandles *handles = _getShaderConstHandles( mPasses.size()-1 );
+   AssertFatal(handles,"");
+   for(int i = 0; i < rpd.mNumTex; i++)
+   { 
+      if(rpd.mSamplerNames[i].isEmpty())
+      {
+         handles->mTexHandlesSC[i] = newPass->shader->getShaderConstHandle( String::EmptyString );
+         handles->mRTParamsSC[i] = newPass->shader->getShaderConstHandle( String::EmptyString );
+         continue;
+      }
+
+      String samplerName = rpd.mSamplerNames[i];
+      if( !samplerName.startsWith("$"))
+         samplerName.insert(0, "$");
+
+      GFXShaderConstHandle *handle = newPass->shader->getShaderConstHandle( samplerName ); 
+
+      handles->mTexHandlesSC[i] = handle;
+      handles->mRTParamsSC[i] = newPass->shader->getShaderConstHandle( String::ToString( "$rtParams%s", samplerName.c_str()+1 ) ); 
+      
+      AssertFatal( handle,"");
+   }
+
    // Give each active feature a chance to create specialized shader consts.
    for( U32 i=0; i < FEATUREMGR->getFeatureCount(); i++ )
    {
@@ -705,6 +759,7 @@ void ProcessedShaderMaterial::setTextureStages( SceneRenderState *state, const S
    PROFILE_SCOPE( ProcessedShaderMaterial_SetTextureStages );
 
    ShaderConstHandles *handles = _getShaderConstHandles(pass);
+   AssertFatal(handles,"");
 
    // Set all of the textures we need to render the give pass.
 #ifdef TORQUE_DEBUG

+ 3 - 0
Engine/source/shaderGen/HLSL/bumpHLSL.cpp

@@ -222,12 +222,14 @@ void BumpFeatHLSL::setTexData(   Material::StageData &stageDat,
    if ( fd.features[MFT_NormalMap] )
    {
       passData.mTexType[ texIndex ] = Material::Bump;
+      passData.mSamplerNames[ texIndex ] = "bumpMap";
       passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap );
    }
 
    if ( fd.features[ MFT_DetailNormalMap ] )
    {
       passData.mTexType[ texIndex ] = Material::DetailBump;
+      passData.mSamplerNames[ texIndex ] = "detailBumpMap";
       passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap );
    }
 }
@@ -382,6 +384,7 @@ void ParallaxFeatHLSL::setTexData(  Material::StageData &stageDat,
    GFXTextureObject *tex = stageDat.getTex( MFT_NormalMap );
    if ( tex )
    {
+      passData.mSamplerNames[ texIndex ] = "bumpMap";
       passData.mTexType[ texIndex ] = Material::Bump;
       passData.mTexSlot[ texIndex++ ].texObject = tex;
    }

+ 1 - 0
Engine/source/shaderGen/HLSL/pixSpecularHLSL.cpp

@@ -147,6 +147,7 @@ void SpecularMapHLSL::setTexData( Material::StageData &stageDat,
    if ( tex )
    {
       passData.mTexType[ texIndex ] = Material::Standard;
+      passData.mSamplerNames[ texIndex ] = "specularMap";
       passData.mTexSlot[ texIndex++ ].texObject = tex;
    }
 }

+ 21 - 4
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp

@@ -985,7 +985,10 @@ void DiffuseMapFeatHLSL::setTexData(   Material::StageData &stageDat,
 {
    GFXTextureObject *tex = stageDat.getTex( MFT_DiffuseMap );
    if ( tex )
+   {
+      passData.mSamplerNames[ texIndex ] = "diffuseMap";
       passData.mTexSlot[ texIndex++ ].texObject = tex;
+   }
 }
 
 
@@ -1069,7 +1072,10 @@ void OverlayTexFeatHLSL::setTexData(   Material::StageData &stageDat,
 {
    GFXTextureObject *tex = stageDat.getTex( MFT_OverlayMap );
    if ( tex )
+   {
+      passData.mSamplerNames[texIndex] = "overlayMap";
       passData.mTexSlot[ texIndex++ ].texObject = tex;
+   }
 }
 
 
@@ -1257,6 +1263,7 @@ void LightmapFeatHLSL::setTexData(  Material::StageData &stageDat,
                                     U32 &texIndex )
 {
    GFXTextureObject *tex = stageDat.getTex( MFT_LightMap );
+   passData.mSamplerNames[ texIndex ] = "lightMap";
    if ( tex )
       passData.mTexSlot[ texIndex++ ].texObject = tex;
    else
@@ -1386,6 +1393,7 @@ void TonemapFeatHLSL::setTexData(  Material::StageData &stageDat,
    if ( tex )
    {
       passData.mTexType[ texIndex ] = Material::ToneMapTex;
+      passData.mSamplerNames[ texIndex ] = "toneMap";
       passData.mTexSlot[ texIndex++ ].texObject = tex;
    }
 }
@@ -1576,7 +1584,10 @@ void DetailFeatHLSL::setTexData( Material::StageData &stageDat,
 {
    GFXTextureObject *tex = stageDat.getTex( MFT_DetailMap );
    if ( tex )
+   {
+      passData.mSamplerNames[texIndex] = "detailMap";
       passData.mTexSlot[ texIndex++ ].texObject = tex;
+   }
 }
 
 
@@ -1846,22 +1857,27 @@ void ReflectCubeFeatHLSL::setTexData(  Material::StageData &stageDat,
        !passData.mFeatureData.features[MFT_NormalMap] )
    {
       GFXTextureObject *tex = stageDat.getTex( MFT_DetailMap );
-      if (  tex &&
-            stageFeatures.features[MFT_DiffuseMap] )
+      if (  tex && stageFeatures.features[MFT_DiffuseMap] )
+      {
+         passData.mSamplerNames[ texIndex ] = "diffuseMap";
          passData.mTexSlot[ texIndex++ ].texObject = tex;
+      }
       else
       {
          tex = stageDat.getTex( MFT_NormalMap );
 
-         if (  tex &&
-               stageFeatures.features[ MFT_NormalMap ] )
+         if (  tex && stageFeatures.features[ MFT_NormalMap ] )
+         {
+            passData.mSamplerNames[ texIndex ] = "bumpMap";
             passData.mTexSlot[ texIndex++ ].texObject = tex;
       }
    }
+   }
    
    if( stageDat.getCubemap() )
    {
       passData.mCubeMap = stageDat.getCubemap();
+      passData.mSamplerNames[texIndex] = "cubeMap";
       passData.mTexType[texIndex++] = Material::Cube;
    }
    else
@@ -1869,6 +1885,7 @@ void ReflectCubeFeatHLSL::setTexData(  Material::StageData &stageDat,
       if( stageFeatures.features[MFT_CubeMap] )
       {
          // assuming here that it is a scenegraph cubemap
+         passData.mSamplerNames[texIndex] = "cubeMap";
          passData.mTexType[texIndex++] = Material::SGCube;
       }
    }

+ 2 - 2
Engine/source/shaderGen/shaderGen.cpp

@@ -443,7 +443,7 @@ void ShaderGen::_printPixShader( Stream &stream )
    mPrinter->printPixelShaderCloser(stream);
 }
 
-GFXShader* ShaderGen::getShader( const MaterialFeatureData &featureData, const GFXVertexFormat *vertexFormat, const Vector<GFXShaderMacro> *macros )
+GFXShader* ShaderGen::getShader( const MaterialFeatureData &featureData, const GFXVertexFormat *vertexFormat, const Vector<GFXShaderMacro> *macros, const Vector<String> &samplers )
 {
    PROFILE_SCOPE( ShaderGen_GetShader );
 
@@ -488,7 +488,7 @@ GFXShader* ShaderGen::getShader( const MaterialFeatureData &featureData, const G
 
    GFXShader *shader = GFX->createShader();
    shader->mInstancingFormat.copy( mInstancingFormat ); // TODO: Move to init() below!
-   if ( !shader->init( vertFile, pixFile, pixVersion, shaderMacros ) )
+   if ( !shader->init( vertFile, pixFile, pixVersion, shaderMacros, samplers ) )
    {
       delete shader;
       return NULL;

+ 1 - 1
Engine/source/shaderGen/shaderGen.h

@@ -155,7 +155,7 @@ public:
                         Vector<GFXShaderMacro> &macros );
 
    // Returns a shader that implements the features listed by dat.
-   GFXShader* getShader( const MaterialFeatureData &dat, const GFXVertexFormat *vertexFormat, const Vector<GFXShaderMacro> *macros );
+   GFXShader* getShader( const MaterialFeatureData &dat, const GFXVertexFormat *vertexFormat, const Vector<GFXShaderMacro> *macros, const Vector<String> &samplers );
 
    // This will delete all of the procedural shaders that we have.  Used to regenerate shaders when
    // the ShaderFeatures have changed (due to lighting system change, or new plugin)

+ 23 - 9
Engine/source/terrain/terrCellMaterial.cpp

@@ -46,6 +46,27 @@ AFTER_MODULE_INIT( MaterialManager )
 
 Vector<TerrainCellMaterial*> TerrainCellMaterial::smAllMaterials;
 
+Vector<String> _initSamplerNames()
+{
+   Vector<String> samplerNames;
+   samplerNames.push_back("$baseTexMap");
+   samplerNames.push_back("$layerTex");   
+   samplerNames.push_back("$macrolayerTex");   
+   samplerNames.push_back("$lightMapTex");
+   samplerNames.push_back("$lightInfoBuffer");
+   for(int i = 0; i < 3; ++i)
+   {
+      samplerNames.push_back(avar("$normalMap%d",i));
+      samplerNames.push_back(avar("$detailMap%d",i));
+      samplerNames.push_back(avar("$macroMap%d",i));
+   }   
+
+   return samplerNames;
+}
+
+
+const Vector<String> TerrainCellMaterial::mSamplerNames = _initSamplerNames();
+
 TerrainCellMaterial::TerrainCellMaterial()
    :  mCurrPass( 0 ),
       mTerrain( NULL ),
@@ -460,7 +481,7 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
          const bool logErrors = matCount == 1;
          GFXShader::setLogging( logErrors, true );
 
-         pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL );
+         pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL, mSamplerNames );
       }
 
       // If we got a shader then we can continue.
@@ -499,14 +520,7 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
    pass->oneOverTerrainSize = pass->shader->getShaderConstHandle( "$oneOverTerrainSize" );
    pass->squareSize = pass->shader->getShaderConstHandle( "$squareSize" );
 
-   // NOTE: We're assuming rtParams0 here as we know its the only
-   // render target we currently get in a terrain material and the
-   // DeferredRTLightingFeatHLSL will always use 0.
-   //
-   // This could change in the future and we would need to fix
-   // the ShaderFeature API to allow us to do this right.
-   //
-   pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParams0" );
+   pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParamslightInfoBuffer" );
 
    // Now prepare the basic stateblock.
    GFXStateBlockDesc desc;

+ 2 - 0
Engine/source/terrain/terrCellMaterial.h

@@ -144,6 +144,8 @@ protected:
 
    U32 mCurrPass;
 
+   static const Vector<String> mSamplerNames;
+
    GFXTexHandle mBaseMapTexture;
 
    GFXTexHandle mLayerMapTexture;