Example #1
0
GFXShader* ShaderGen::getShader( const MaterialFeatureData &featureData, const GFXVertexFormat *vertexFormat, const Vector<GFXShaderMacro> *macros )
{
   PROFILE_SCOPE( ShaderGen_GetShader );

   const FeatureSet &features = featureData.codify();

   // Build a description string from the features
   // and vertex format combination ( and macros ).
   String shaderDescription = vertexFormat->getDescription() + features.getDescription();
   if ( macros && !macros->empty() )
   {
      String macroStr;
      GFXShaderMacro::stringize( *macros, &macroStr );
      shaderDescription += macroStr;
   }

   // Generate a single 64bit hash from the description string.
   //
   // Don't get paranoid!  This has 1 in 18446744073709551616
   // chance for collision... it won't happen in this lifetime.
   //
   U64 hash = Torque::hash64( (const U8*)shaderDescription.c_str(), shaderDescription.length(), 0 );
   hash = convertHostToLEndian(hash);
   U32 high = (U32)( hash >> 32 );
   U32 low = (U32)( hash & 0x00000000FFFFFFFF );
   String cacheKey = String::ToString( "%x%x", high, low );

   // return shader if exists
   GFXShader *match = mProcShaders[cacheKey];
   if ( match )
      return match;

   // if not, then create it
   char vertFile[256];
   char pixFile[256];
   F32  pixVersion;

   Vector<GFXShaderMacro> shaderMacros;
   shaderMacros.push_back( GFXShaderMacro( "TORQUE_SHADERGEN" ) );
   if ( macros )
      shaderMacros.merge( *macros );
   generateShader( featureData, vertFile, pixFile, &pixVersion, vertexFormat, cacheKey, shaderMacros );

   GFXShader *shader = GFX->createShader();
   shader->mInstancingFormat.copy( mInstancingFormat ); // TODO: Move to init() below!
   if ( !shader->init( vertFile, pixFile, pixVersion, shaderMacros ) )
   {
      delete shader;
      return NULL;
   }

   mProcShaders[cacheKey] = shader;

   return shader;
}
Example #2
0
GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> &macros )
{
   F32 pixver = mPixVersion;
   if ( mUseDevicePixVersion )
      pixver = getMax( pixver, GFX->getPixelShaderVersion() );

   // Enable shader error logging.
   GFXShader::setLogging( true, true );

   GFXShader *shader = GFX->createShader();
   bool success = false;

   // Initialize the right shader type.
   switch( GFX->getAdapterType() )
   {
      case Direct3D9_360:
      case Direct3D9:
      {
         success = shader->init( mDXVertexShaderName, 
                                 mDXPixelShaderName, 
                                 pixver,
                                 macros );
         break;
      }

      case OpenGL:
      {
         success = shader->init( mOGLVertexShaderName,
                                 mOGLPixelShaderName,
                                 pixver,
                                 macros );
         break;
      }
         
      default:
         // Other device types are assumed to not support shaders.
         success = false;
         break;
   }

   // If we failed to load the shader then
   // cleanup and return NULL.
   if ( !success )
      SAFE_DELETE( shader );

   return shader;
}
Example #3
0
GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> &macros )
{
   F32 pixver = mPixVersion;
   if ( mUseDevicePixVersion )
      pixver = getMax( pixver, GFX->getPixelShaderVersion() );

   // Enable shader error logging.
   GFXShader::setLogging( true, true );

   GFXShader *shader = GFX->createShader();
   bool success = false;

   Vector<String> samplers;
   samplers.setSize(ShaderData::NumTextures);
   for(int i = 0; i < ShaderData::NumTextures; ++i)
      samplers[i] = mSamplerNames[i][0] == '$' ? mSamplerNames[i] : "$"+mSamplerNames[i];

   // Initialize the right shader type.
   switch( GFX->getAdapterType() )
   {
      case Direct3D9_360:
      case Direct3D9:
      case Direct3D11:
      {
         success = shader->init( mDXVertexShaderName, 
                                 mDXPixelShaderName, 
                                 pixver,
                                 macros,
                                 samplers);
         break;
      }

      case OpenGL:
      {
         success = shader->init( mOGLVertexShaderName,
                                 mOGLPixelShaderName,
                                 pixver,
                                 macros,
                                 samplers);
         break;
      }
         
      default:
         // Other device types are assumed to not support shaders.
         success = false;
         break;
   }

#if defined(TORQUE_DEBUG)
   //Assert Sampler registers
   const Vector<GFXShaderConstDesc>& descs = shader->getShaderConstDesc();
   for(int i = 0; i < descs.size(); ++i)
   {
      if(descs[i].constType != GFXSCT_Sampler && descs[i].constType != GFXSCT_SamplerCube)
         continue;
      
      GFXShaderConstHandle *handle = shader->findShaderConstHandle(descs[i].name);
      if(!handle || !handle->isValid())
         continue;

      int reg = handle->getSamplerRegister();
      if( descs[i].name != samplers[reg] )
      {
         const char *err = avar("ShaderData(%s): samplerNames[%d] = \"%s\" are diferent to sampler in shader: %s : register(S%d)"
            ,getName(), reg, samplers[reg].c_str(), handle->getName().c_str(), reg);
         Con::printf(err);
         GFXAssertFatal(0, err);
      }
   }
#endif

   // If we failed to load the shader then
   // cleanup and return NULL.
   if ( !success )
      SAFE_DELETE( shader );

   return shader;
}