//----------------------------------------------------------------------------- GpuProgramPtr ProgramManager::createGpuProgram(Program* shaderProgram, ProgramWriter* programWriter, const String& language, const String& profiles, const StringVector& profilesList, const String& cachePath) { stringstream sourceCodeStringStream; // Generate source code. programWriter->writeSourceCode(sourceCodeStringStream, shaderProgram); String source = sourceCodeStringStream.str(); // Generate program name. String programName = generateHash(source); if (shaderProgram->getType() == GPT_VERTEX_PROGRAM) { programName += "_VS"; } else if (shaderProgram->getType() == GPT_FRAGMENT_PROGRAM) { programName += "_FS"; } // Try to get program by name. HighLevelGpuProgramPtr pGpuProgram = HighLevelGpuProgramManager::getSingleton().getByName( programName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); if(pGpuProgram) { return static_pointer_cast<GpuProgram>(pGpuProgram); } // Case the program doesn't exist yet. // Create new GPU program. pGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, language, shaderProgram->getType()); // Case cache directory specified -> create program from file. if (!cachePath.empty()) { const String programFullName = programName + "." + language; const String programFileName = cachePath + programFullName; std::ifstream programFile; // Check if program file already exist. programFile.open(programFileName.c_str()); // Case we have to write the program to a file. if (!programFile) { std::ofstream outFile(programFileName.c_str()); if (!outFile) return GpuProgramPtr(); outFile << source; outFile.close(); } else { // use program file version StringStream buffer; programFile >> buffer.rdbuf(); source = buffer.str(); } } pGpuProgram->setSource(source); pGpuProgram->setParameter("entry_point", shaderProgram->getEntryPointFunction()->getName()); if (language == "hlsl") { // HLSL program requires specific target profile settings - we have to split the profile string. StringVector::const_iterator it = profilesList.begin(); StringVector::const_iterator itEnd = profilesList.end(); for (; it != itEnd; ++it) { if (GpuProgramManager::getSingleton().isSyntaxSupported(*it)) { pGpuProgram->setParameter("target", *it); break; } } pGpuProgram->setParameter("enable_backwards_compatibility", "true"); pGpuProgram->setParameter("column_major_matrices", StringConverter::toString(shaderProgram->getUseColumnMajorMatrices())); } pGpuProgram->setParameter("profiles", profiles); pGpuProgram->load(); // Case an error occurred. if (pGpuProgram->hasCompileError()) { //! [debug_break] pGpuProgram.reset(); //! [debug_break] return GpuProgramPtr(pGpuProgram); } // Add the created GPU program to local cache. if (pGpuProgram->getType() == GPT_VERTEX_PROGRAM) { mVertexShaderMap[programName] = pGpuProgram; } else if (pGpuProgram->getType() == GPT_FRAGMENT_PROGRAM) { mFragmentShaderMap[programName] = pGpuProgram; } return static_pointer_cast<GpuProgram>(pGpuProgram); }