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, ¯oStr ); 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; }
Shader* ShaderManager::getShader(const ShaderFeaturesLocal& sfl) { if(mShaderMap.find(sfl) != mShaderMap.end()) { return mShaderMap[sfl]; } else { return generateShader(sfl); } }
void ShaderManager::assignShader(VisualMaterial* mat) { ShadingFeatures shadingFeaturesToGenerate = ShadingFeatures( mat->getShadingFeatures() & (mEnabledShadingFeatures) ); if( //(WindowManager::getInstance().getAvailableOpenGLVersion().x >= 4 ) //&& ( (mCurrentRenderingTechnique == RENDERING_TECHNIQUE_SHADOWMAP_GENERATION) || (mCurrentRenderingTechnique == RENDERING_TECHNIQUE_DEPTH_IMAGE_GENERATION) || (mCurrentRenderingTechnique == RENDERING_TECHNIQUE_POSITION_IMAGE_GENERATION) || (mCurrentRenderingTechnique == RENDERING_TECHNIQUE_PRIMITIVE_ID_RASTERIZATION) ) ) { //mask all shading features of those "none-lighting-techniques" but tessellation reinterpret_cast<unsigned int&>(shadingFeaturesToGenerate) &= ShadingFeatures( SHADING_FEATURE_NONE | SHADING_FEATURE_TESSELATION ); } if(mat->getType() == VISUAL_MATERIAL_TYPE_SKYDOME_RENDERING) { //for skydome, cube mapping must always be enabled, no matter what the gloable state says ;( reinterpret_cast<unsigned int&>(shadingFeaturesToGenerate) |= SHADING_FEATURE_CUBE_MAPPING; } ShaderFeaturesLocal sfl = ShaderFeaturesLocal( mCurrentRenderingTechnique, mCurrentRenderTargetTextureType, mat->getType(), //permit only the enabled features! shadingFeaturesToGenerate, mat->isInstanced() ); // if( (!tesselationIsEnabled()) ) // { // //mask out tesselation feature! // reinterpret_cast<unsigned int&>(sfl.shadingFeatures) &= (~SHADING_FEATURE_TESSELATION); // } if(mShaderMap.find(sfl) == mShaderMap.end()) { mat->setShader(generateShader(sfl)); } else { mat->setShader(mShaderMap[sfl]); } }