//----------------------------------------------------------------------------- GLES2FrameBufferObject::GLES2FrameBufferObject(GLES2FBOManager *manager, uint fsaa): mManager(manager), mNumSamples(fsaa) { GLES2Support* glSupport = getGLES2SupportRef(); // Generate framebuffer object OGRE_CHECK_GL_ERROR(glGenFramebuffers(1, &mFB)); if(glSupport->checkExtension("GL_EXT_debug_label")) { OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glLabelObjectEXT(GL_BUFFER_OBJECT_EXT, mFB, 0, ("FBO #" + StringConverter::toString(mFB)).c_str())); } mNumSamples = 0; mMultisampleFB = 0; // Check multisampling if supported if(glSupport->hasMinGLVersion(3, 0)) { // Check samples supported OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFB)); GLint maxSamples; OGRE_CHECK_GL_ERROR(glGetIntegerv(GL_MAX_SAMPLES_APPLE, &maxSamples)); OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0)); mNumSamples = std::min(mNumSamples, (GLsizei)maxSamples); } // Will we need a second FBO to do multisampling? if (mNumSamples) { OGRE_CHECK_GL_ERROR(glGenFramebuffers(1, &mMultisampleFB)); if(glSupport->checkExtension("GL_EXT_debug_label")) { OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glLabelObjectEXT(GL_BUFFER_OBJECT_EXT, mMultisampleFB, 0, ("MSAA FBO #" + StringConverter::toString(mMultisampleFB)).c_str())); } } else { mMultisampleFB = 0; } // Initialise state mDepth.buffer = 0; mStencil.buffer = 0; for(size_t x = 0; x < OGRE_MAX_MULTIPLE_RENDER_TARGETS; ++x) { mColour[x].buffer=0; } }
GLSLESProgramPipeline::~GLSLESProgramPipeline() { #if GL_EXT_separate_shader_objects && OGRE_PLATFORM != OGRE_PLATFORM_NACL OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glDeleteProgramPipelinesEXT(1, &mGLProgramPipelineHandle)); #endif }
//------------------------------------------------------------------ void GLES2HardwareOcclusionQuery::endOcclusionQuery() { #ifdef GL_EXT_occlusion_query_boolean OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT)); #endif }
//------------------------------------------------------------------ void GLES2HardwareOcclusionQuery::destroyQuery() { #ifdef GL_EXT_occlusion_query_boolean OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glDeleteQueriesEXT(1, &mQueryID)); #endif }
//------------------------------------------------------------------ bool GLES2HardwareOcclusionQuery::pullOcclusionQuery( unsigned int* NumOfFragments ) { #ifdef GL_EXT_occlusion_query_boolean OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glGetQueryObjectuivEXT(mQueryID, GL_QUERY_RESULT_EXT, (GLuint*)NumOfFragments)); mPixelCount = *NumOfFragments; return true; #else return false; #endif }
//------------------------------------------------------------------ void GLES2HardwareOcclusionQuery::createQuery() { // Check for hardware occlusion support #ifdef GL_EXT_occlusion_query_boolean OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glGenQueriesEXT(1, &mQueryID )); #else OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Cannot allocate a Hardware query. This video card doesn't support it, sorry.", "GLES2HardwareOcclusionQuery::GLES2HardwareOcclusionQuery" ); #endif }
//------------------------------------------------------------------ bool GLES2HardwareOcclusionQuery::isStillOutstanding(void) { GLuint available = GL_FALSE; #ifdef GL_EXT_occlusion_query_boolean OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glGetQueryObjectuivEXT(mQueryID, GL_QUERY_RESULT_AVAILABLE_EXT, &available)); #endif // GL_TRUE means a wait would occur return !(available == GL_TRUE); }
void GLES2HardwareVertexBuffer::createBuffer() { OGRE_CHECK_GL_ERROR(glGenBuffers(1, &mBufferId)); if(getGLES2SupportRef()->checkExtension("GL_EXT_debug_label")) { OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glLabelObjectEXT(GL_BUFFER_OBJECT_EXT, mBufferId, 0, ("Vertex Buffer #" + StringConverter::toString(mBufferId)).c_str())); } if (!mBufferId) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Cannot create GL ES vertex buffer", "GLES2HardwareVertexBuffer::GLES2HardwareVertexBuffer"); } static_cast<GLES2HardwareBufferManagerBase*>(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId); OGRE_CHECK_GL_ERROR(glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, NULL, GLES2HardwareBufferManager::getGLUsage(mUsage))); }
bool GLSLESProgram::compile(const bool checkErrors) { if (mCompiled == 1) { return true; } // Only create a shader object if glsl es is supported if (isSupported()) { // Create shader object GLenum shaderType = 0x0000; if (mType == GPT_VERTEX_PROGRAM) { shaderType = GL_VERTEX_SHADER; } else if (mType == GPT_FRAGMENT_PROGRAM) { shaderType = GL_FRAGMENT_SHADER; } OGRE_CHECK_GL_ERROR(mGLShaderHandle = glCreateShader(shaderType)); #if OGRE_PLATFORM != OGRE_PLATFORM_NACL if(getGLES2SupportRef()->checkExtension("GL_EXT_debug_label")) { OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) glLabelObjectEXT(GL_SHADER_OBJECT_EXT, mGLShaderHandle, 0, mName.c_str()); } #endif if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { OGRE_CHECK_GL_ERROR(mGLProgramHandle = glCreateProgram()); #if OGRE_PLATFORM != OGRE_PLATFORM_NACL if(getGLES2SupportRef()->checkExtension("GL_EXT_debug_label")) { OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) glLabelObjectEXT(GL_PROGRAM_OBJECT_EXT, mGLProgramHandle, 0, mName.c_str()); } #endif } } // Add preprocessor extras and main source if (!mSource.empty()) { // Fix up the source in case someone forgot to redeclare gl_Position if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS) && mType == GPT_VERTEX_PROGRAM) { size_t versionPos = mSource.find("#version"); int shaderVersion = StringConverter::parseInt(mSource.substr(versionPos+9, 3)); // Check that it's missing and that this shader has a main function, ie. not a child shader. if(mSource.find("out highp vec4 gl_Position") == String::npos) { if(shaderVersion >= 300) mSource.insert(versionPos+16, "out highp vec4 gl_Position;\nout highp float gl_PointSize;\n"); } if(mSource.find("#extension GL_EXT_separate_shader_objects : require") == String::npos) { if(shaderVersion >= 300) mSource.insert(versionPos+16, "#extension GL_EXT_separate_shader_objects : require\n"); } } #if !OGRE_NO_GLES2_GLSL_OPTIMISER const char *source = (getOptimiserEnabled() && getIsOptimised()) ? mOptimisedSource.c_str() : mSource.c_str(); #else const char *source = mSource.c_str(); #endif OGRE_CHECK_GL_ERROR(glShaderSource(mGLShaderHandle, 1, &source, NULL)); } if (checkErrors) logObjectInfo("GLSL ES compiling: " + mName, mGLShaderHandle); OGRE_CHECK_GL_ERROR(glCompileShader(mGLShaderHandle)); // Check for compile errors OGRE_CHECK_GL_ERROR(glGetShaderiv(mGLShaderHandle, GL_COMPILE_STATUS, &mCompiled)); if(!mCompiled && checkErrors) { String message = logObjectInfo("GLSL ES compile log: " + mName, mGLShaderHandle); checkAndFixInvalidDefaultPrecisionError(message); } // Log a message that the shader compiled successfully. if (mCompiled && checkErrors) logObjectInfo("GLSL ES compiled: " + mName, mGLShaderHandle); if(!mCompiled) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, ((mType == GPT_VERTEX_PROGRAM) ? "Vertex Program " : "Fragment Program ") + mName + " failed to compile. See compile log above for details.", "GLSLESProgram::compile"); } return (mCompiled == 1); }
void GLSLESProgramPipeline::compileAndLink() { #if GL_EXT_separate_shader_objects && 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(mVertexProgram && !mVertexProgram->isLinked()) { try { mVertexProgram->getGLSLProgram()->compile(true); } catch (Exception& e) { LogManager::getSingleton().stream() << e.getDescription(); mTriedToLinkAndFailed = true; return; } GLuint programHandle = mVertexProgram->getGLSLProgram()->getGLProgramHandle(); OGRE_CHECK_GL_ERROR(glProgramParameteriEXT(programHandle, GL_PROGRAM_SEPARABLE_EXT, GL_TRUE)); mVertexProgram->getGLSLProgram()->attachToProgramObject(programHandle); OGRE_CHECK_GL_ERROR(glLinkProgram(programHandle)); OGRE_CHECK_GL_ERROR(glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus)); if(linkStatus) { mVertexProgram->setLinked(linkStatus); mLinked |= VERTEX_PROGRAM_LINKED; } mTriedToLinkAndFailed = !linkStatus; logObjectInfo( getCombinedName() + String("GLSL vertex program result : "), programHandle ); setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded()); } // Compile and attach Fragment Program if(mFragmentProgram && !mFragmentProgram->isLinked()) { try { mFragmentProgram->getGLSLProgram()->compile(true); } catch (Exception& e) { LogManager::getSingleton().stream() << e.getDescription(); mTriedToLinkAndFailed = true; return; } GLuint programHandle = mFragmentProgram->getGLSLProgram()->getGLProgramHandle(); OGRE_CHECK_GL_ERROR(glProgramParameteriEXT(programHandle, GL_PROGRAM_SEPARABLE_EXT, GL_TRUE)); mFragmentProgram->getGLSLProgram()->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; logObjectInfo( getCombinedName() + String("GLSL fragment program result : "), programHandle ); } if(mLinked) { if(mVertexProgram && mVertexProgram->isLinked()) { OGRE_CHECK_GL_ERROR(glUseProgramStagesEXT(mGLProgramPipelineHandle, GL_VERTEX_SHADER_BIT_EXT, mVertexProgram->getGLSLProgram()->getGLProgramHandle())); } if(mFragmentProgram && mFragmentProgram->isLinked()) { OGRE_CHECK_GL_ERROR(glUseProgramStagesEXT(mGLProgramPipelineHandle, GL_FRAGMENT_SHADER_BIT_EXT, mFragmentProgram->getGLSLProgram()->getGLProgramHandle())); } // Validate pipeline logObjectInfo( getCombinedName() + String("GLSL program pipeline result : "), mGLProgramPipelineHandle ); #if GL_EXT_debug_label && OGRE_PLATFORM != OGRE_PLATFORM_NACL if(mVertexProgram && mFragmentProgram) OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) glLabelObjectEXT(GL_PROGRAM_PIPELINE_OBJECT_EXT, mGLProgramPipelineHandle, 0, (mVertexProgram->getName() + "/" + mFragmentProgram->getName()).c_str()); #endif } #endif }