//----------------------------------------------------------------------------------- GpuProgramPtr ShaderManager::getGpuProgram(HlmsDatablock* dataBlock) { uint32 hash = dataBlock->getHash(); map<uint32, GpuProgramPtr>::iterator it = mShaderCache.find(hash); if (it != mShaderCache.end()) { return (*it).second; } String typeStr = FilePatterns[dataBlock->getShaderType()]; std::stringstream sstream; sstream << std::hex << hash; std::string hashString = sstream.str(); String name = hashString + typeStr; // generate the shader code String code = dataBlock->getTemplate()->getTemplate(); StringVectorPtr pieces = mShaderPiecesManager->getPieces(dataBlock->getLanguage(), dataBlock->getShaderType()); code = ShaderGenerator::parse(code, *(dataBlock->getPropertyMap()), pieces); GpuProgramPtr gpuProgram = createGpuProgram(name, code, dataBlock); mShaderCache[hash] = gpuProgram; return gpuProgram; }
//----------------------------------------------------------------------------- bool ProgramManager::createGpuPrograms(ProgramSet* programSet) { // Before we start we need to make sure that the pixel shader input // parameters are the same as the vertex output, this required by // shader models 4 and 5. // This change may incrase the number of register used in older shader // models - this is why the check is present here. bool isVs4 = GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0"); if (isVs4) { synchronizePixelnToBeVertexOut(programSet); } // Grab the matching writer. const String& language = ShaderGenerator::getSingleton().getTargetLanguage(); ProgramWriterIterator itWriter = mProgramWritersMap.find(language); ProgramWriter* programWriter = NULL; // No writer found -> create new one. if (itWriter == mProgramWritersMap.end()) { programWriter = ProgramWriterManager::getSingletonPtr()->createProgramWriter(language); mProgramWritersMap[language] = programWriter; } else { programWriter = itWriter->second; } ProgramProcessorIterator itProcessor = mProgramProcessorsMap.find(language); ProgramProcessor* programProcessor = NULL; if (itProcessor == mProgramProcessorsMap.end()) { OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Could not find processor for language '" + language, "ProgramManager::createGpuPrograms"); } programProcessor = itProcessor->second; bool success; // Call the pre creation of GPU programs method. success = programProcessor->preCreateGpuPrograms(programSet); if (success == false) return false; // Create the vertex shader program. GpuProgramPtr vsGpuProgram; vsGpuProgram = createGpuProgram(programSet->getCpuVertexProgram(), programWriter, language, ShaderGenerator::getSingleton().getVertexShaderProfiles(), ShaderGenerator::getSingleton().getVertexShaderProfilesList(), ShaderGenerator::getSingleton().getShaderCachePath()); if (vsGpuProgram.isNull()) return false; programSet->setGpuVertexProgram(vsGpuProgram); //update flags programSet->getGpuVertexProgram()->setSkeletalAnimationIncluded( programSet->getCpuVertexProgram()->getSkeletalAnimationIncluded()); // Create the fragment shader program. GpuProgramPtr psGpuProgram; psGpuProgram = createGpuProgram(programSet->getCpuFragmentProgram(), programWriter, language, ShaderGenerator::getSingleton().getFragmentShaderProfiles(), ShaderGenerator::getSingleton().getFragmentShaderProfilesList(), ShaderGenerator::getSingleton().getShaderCachePath()); if (psGpuProgram.isNull()) return false; programSet->setGpuFragmentProgram(psGpuProgram); // Call the post creation of GPU programs method. success = programProcessor->postCreateGpuPrograms(programSet); if (success == false) return false; return true; }