//----------------------------------------------------------------------- void GLSLESLinkProgram::activate(void) { if (!mLinked && !mTriedToLinkAndFailed) { glGetError(); // Clean up the error. Otherwise will flood log. mGLHandle = glCreateProgram(); GL_CHECK_ERROR if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() && GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) ) { getMicrocodeFromCache(); } else { #ifdef OGRE_USE_GLES2_GLSL_OPTIMISER // check CmdParams for each shader type to see if we should optimize String paramStr = mVertexProgram->getGLSLProgram()->getParameter("use_optimiser"); if((paramStr == "true") || paramStr.empty()) { GLSLESLinkProgramManager::getSingleton().optimiseShaderSource(mVertexProgram); } paramStr = mFragmentProgram->getGLSLProgram()->getParameter("use_optimiser"); if((paramStr == "true") || paramStr.empty()) { GLSLESLinkProgramManager::getSingleton().optimiseShaderSource(mFragmentProgram); } #endif compileAndLink(); } buildGLUniformReferences(); }
//----------------------------------------------------------------------- void GLSLProgramPipeline::activate(void) { if (!mLinked && !mTriedToLinkAndFailed) { if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() && GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) ) { getMicrocodeFromCache(); } else { compileAndLink(); } extractLayoutQualifiers(); buildGLUniformReferences(); } _useProgram(); }
void GLSLESProgramPipeline::compileAndLink() { #if OGRE_PLATFORM != OGRE_PLATFORM_NACL GLint linkStatus = 0; OGRE_CHECK_GL_ERROR(glGenProgramPipelinesEXT(1, &mGLProgramPipelineHandle)); OGRE_CHECK_GL_ERROR(glBindProgramPipelineEXT(mGLProgramPipelineHandle)); // Compile and attach Vertex Program if(getVertexProgram()) { if(getVertexProgram()->isLinked()) { mLinked |= VERTEX_PROGRAM_LINKED; } else if(getMicrocodeFromCache( getVertexProgram()->getName(), getVertexProgram()->createGLProgramHandle())) { getVertexProgram()->setLinked(true); mLinked |= VERTEX_PROGRAM_LINKED; mTriedToLinkAndFailed = false; } else { if(!getVertexProgram()->compile(true)) { LogManager::getSingleton().stream(LML_CRITICAL) << "Vertex Program " << getVertexProgram()->getName() << " failed to compile. See compile log above for details."; mTriedToLinkAndFailed = true; return; } GLuint programHandle = getVertexProgram()->getGLProgramHandle(); bindFixedAttributes( programHandle ); OGRE_CHECK_GL_ERROR(glProgramParameteriEXT(programHandle, GL_PROGRAM_SEPARABLE_EXT, GL_TRUE)); getVertexProgram()->attachToProgramObject(programHandle); OGRE_CHECK_GL_ERROR(glLinkProgram(programHandle)); OGRE_CHECK_GL_ERROR(glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus)); if(linkStatus) { getVertexProgram()->setLinked(linkStatus); mLinked |= VERTEX_PROGRAM_LINKED; } mTriedToLinkAndFailed = !linkStatus; GLSLES::logObjectInfo( getCombinedName() + String("GLSL vertex program result : "), programHandle ); setSkeletalAnimationIncluded(getVertexProgram()->isSkeletalAnimationIncluded()); } } // Compile and attach Fragment Program if(mFragmentProgram) { if(mFragmentProgram->isLinked()) { mLinked |= FRAGMENT_PROGRAM_LINKED; } else if(getMicrocodeFromCache( mFragmentProgram->getName(), mFragmentProgram->createGLProgramHandle())) { mFragmentProgram->setLinked(true); mLinked |= FRAGMENT_PROGRAM_LINKED; mTriedToLinkAndFailed = false; } else { if(!mFragmentProgram->compile(true)) { LogManager::getSingleton().stream(LML_CRITICAL) << "Fragment Program " << mFragmentProgram->getName() << " failed to compile. See compile log above for details."; mTriedToLinkAndFailed = true; return; } GLuint programHandle = mFragmentProgram->getGLProgramHandle(); OGRE_CHECK_GL_ERROR(glProgramParameteriEXT(programHandle, GL_PROGRAM_SEPARABLE_EXT, GL_TRUE)); mFragmentProgram->attachToProgramObject(programHandle); OGRE_CHECK_GL_ERROR(glLinkProgram(programHandle)); OGRE_CHECK_GL_ERROR(glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus)); if(linkStatus) { mFragmentProgram->setLinked(linkStatus); mLinked |= FRAGMENT_PROGRAM_LINKED; } mTriedToLinkAndFailed = !linkStatus; GLSLES::logObjectInfo( getCombinedName() + String("GLSL fragment program result : "), programHandle ); } } if(mLinked) { if(getVertexProgram() && getVertexProgram()->isLinked()) { OGRE_CHECK_GL_ERROR(glUseProgramStagesEXT(mGLProgramPipelineHandle, GL_VERTEX_SHADER_BIT_EXT, getVertexProgram()->getGLProgramHandle())); _writeToCache(getVertexProgram()->getName(), getVertexProgram()->getGLProgramHandle()); } if(mFragmentProgram && mFragmentProgram->isLinked()) { OGRE_CHECK_GL_ERROR(glUseProgramStagesEXT(mGLProgramPipelineHandle, GL_FRAGMENT_SHADER_BIT_EXT, mFragmentProgram->getGLProgramHandle())); _writeToCache(mFragmentProgram->getName(), mFragmentProgram->getGLProgramHandle()); } // Validate pipeline GLSLES::logObjectInfo( getCombinedName() + String("GLSL program pipeline result : "), mGLProgramPipelineHandle ); if(getVertexProgram() && mFragmentProgram && Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_DEBUG)) { glLabelObjectEXT(GL_PROGRAM_PIPELINE_OBJECT_EXT, mGLProgramPipelineHandle, 0, (getVertexProgram()->getName() + "/" + mFragmentProgram->getName()).c_str()); } } #endif }
//----------------------------------------------------------------------- void CgProgram::loadFromSource(void) { selectProfile(); if ( GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(String("CG_") + mName) ) { getMicrocodeFromCache(); } else { compileMicrocode(); } if (mDelegate) { mDelegate->setSource(mProgramString); mDelegate->setAdjacencyInfoRequired(isAdjacencyInfoRequired()); if (mSelectedCgProfile == CG_PROFILE_GLSLG) { // need to set input and output operations if (mInputOp == CG_POINT) { mDelegate->setParameter("input_operation_type", "point_list"); } else if (mInputOp == CG_LINE) { mDelegate->setParameter("input_operation_type", "line_strip"); } else if (mInputOp == CG_LINE_ADJ) { mDelegate->setParameter("input_operation_type", "line_strip"); mDelegate->setAdjacencyInfoRequired(true); } else if (mInputOp == CG_TRIANGLE) { mDelegate->setParameter("input_operation_type", "triangle_strip"); } else if (mInputOp == CG_TRIANGLE_ADJ) { mDelegate->setParameter("input_operation_type", "triangle_strip"); mDelegate->setAdjacencyInfoRequired(true); } if (mOutputOp == CG_POINT_OUT) mDelegate->setParameter("output_operation_type", "point_list"); else if (mOutputOp == CG_LINE_OUT) mDelegate->setParameter("output_operation_type", "line_strip"); else if (mOutputOp == CG_TRIANGLE_OUT) mDelegate->setParameter("output_operation_type", "triangle_strip"); } if (getHighLevelLanguage() == "glsl") { // for GLSL, also ensure we explicitly bind samplers to their register // otherwise, GLSL will assign them in the order first used, which is // not what we want. GpuProgramParametersSharedPtr params = mDelegate->getDefaultParameters(); for (map<String,int>::type::iterator i = mSamplerRegisterMap.begin(); i != mSamplerRegisterMap.end(); ++i) params->setNamedConstant(i->first, i->second); } mDelegate->load(); } }