//----------------------------------------------------------------------------- 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; }
//--------------------------------------------------------------------- //--------------------------------------------------------------------- void ShadowVolumeExtrudeProgram::initialise(void) { if (!mInitialised) { String syntax; bool vertexProgramFinite[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = { false, false, false, false, true, true, true, true }; bool vertexProgramDebug[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = { false, true, false, true, false, true, false, true }; Light::LightTypes vertexProgramLightTypes[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = { Light::LT_POINT, Light::LT_POINT, Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL, Light::LT_POINT, Light::LT_POINT, Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL }; // load hardware extrusion programs for point & dir lights if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1")) { // ARBvp1 syntax = "arbvp1"; } else if (GpuProgramManager::getSingleton().isSyntaxSupported("vs_1_1")) { syntax = "vs_1_1"; } else if (GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0")) { syntax = "vs_4_0"; } else { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Vertex programs are supposedly supported, but neither " "arbvp1, vs_1_1 nor vs_4_0 syntaxes are present.", "SceneManager::initShadowVolumeMaterials"); } // Create all programs for (unsigned short v = 0; v < OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS; ++v) { // Create debug extruders if (GpuProgramManager::getSingleton().getByName( programNames[v]).isNull()) { if (syntax == "vs_4_0") { HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton().createProgram( programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, "hlsl", GPT_VERTEX_PROGRAM); vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource( vertexProgramLightTypes[v], syntax, vertexProgramFinite[v], vertexProgramDebug[v])); vp->setParameter("target", syntax); vp->setParameter("entry_point", "vs_main"); vp->load(); if (frgProgramName.empty()) { frgProgramName = "Ogre/ShadowFrgProgram"; HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton().createProgram( frgProgramName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, "hlsl", GPT_FRAGMENT_PROGRAM); fp->setSource(mGeneralFs_4_0); fp->setParameter("target", "ps_4_0"); fp->setParameter("entry_point", "fs_main"); fp->load(); } } else { GpuProgramPtr vp = GpuProgramManager::getSingleton().createProgramFromString( programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, ShadowVolumeExtrudeProgram::getProgramSource( vertexProgramLightTypes[v], syntax, vertexProgramFinite[v], vertexProgramDebug[v]), GPT_VERTEX_PROGRAM, syntax); vp->load(); } } } mInitialised = true; } }
//----------------------------------------------------------------------------- void GLSLProgramProcessor::bindSubShaders(Program* program, GpuProgramPtr pGpuProgram) { if (program->getDependencyCount() > 0) { // Get all attached shaders so we do not attach shaders twice. // maybe GLSLProgram should take care of that ( prevent add duplicate shaders ) String attachedShaders = pGpuProgram->getParameter("attach"); String subShaderDef = ""; for (unsigned int i=0; i < program->getDependencyCount(); ++i) { // Here we append _VS and _FS to the library shaders (so max each lib shader // is compiled twice once as vertex and once as fragment shader) String subShaderName = program->getDependency(i); if (program->getType() == GPT_VERTEX_PROGRAM) { subShaderName += "_VS"; } else { subShaderName += "_FS"; } // Check if the library shader already compiled if(!HighLevelGpuProgramManager::getSingleton().resourceExists(subShaderName)) { // Create the library shader HighLevelGpuProgramPtr pSubGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(subShaderName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TargetLanguage, program->getType()); // Set the source name String sourceName = program->getDependency(i) + "." + TargetLanguage; pSubGpuProgram->setSourceFile(sourceName); pSubGpuProgram->load(); // Prepend the current GLSL version String versionLine = "#version " + StringConverter::toString(Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion()) + "\n"; pSubGpuProgram->setSource(versionLine + pSubGpuProgram->getSource()); // If we have compile errors than stop processing if (pSubGpuProgram->hasCompileError()) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Could not compile shader library from the source file: " + sourceName, "GLSLProgramProcessor::bindSubShaders" ); } mLibraryPrograms.push_back(subShaderName); } // Check if the lib shader already attached to this shader if (attachedShaders.find(subShaderName) == String::npos) { // Append the shader name to subShaders subShaderDef += subShaderName + " "; } } // Check if we have something to attach if (subShaderDef.length() > 0) { pGpuProgram->setParameter("attach", subShaderDef); } } }