FSAA is off by default in the SampleBrowser application for 1.7.2, and when built for the iPhone device (in my case an iTouch 2g) for iOS 4.1, the display would flash alternating black/menu/black/menu (or, instead of black, whatever nonsense was left in the memory). This is related to the FSAA setting.
It took a few days to sort out by I built for iPhone (device, not simulator) from source. Early on the simulator worked fine, but the SampleBrowser application on the device would flash, and NOT animate the menu.
Masterfalcon noted a bug report relating to an Apple API ( glResolveMultisampleFramebufferAPPLE() ) in the function EAGLWindow::swapBuffers where FSAA is applied, but while that was VERY close, it wasn't the problem. In fact, as shipped, the default configuration for the samplebrowser has FSAA set to 0, so the code wasn't even being called.
Then, DanielSefton recognized the problem, suggested setting FSAA to 2, and that caused it to work.
That troubled me to think that non-FSAA display is broken, and I think it is - here's a proposed fix, and the true nature of my inquiry here.
In OgreEAGLWindow.mm, around line 411, this function appears.
Code: Select all
void EAGLWindow::swapBuffers(bool waitForVSync)
{
if (mClosed || mIsExternalGLControl)
{
return;
}
if (mAnimationTimer->getMilliseconds() < kSwapInterval)
{
return;
}
mAnimationTimer->reset();
#if GL_APPLE_framebuffer_multisample
if(mContext->mIsMultiSampleSupported && mContext->mNumSamples > 0)
{
glDisable(GL_SCISSOR_TEST);
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, mContext->mFSAAFramebuffer);
GL_CHECK_ERROR
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, mContext->mViewFramebuffer);
GL_CHECK_ERROR
glResolveMultisampleFramebufferAPPLE();
GL_CHECK_ERROR
}
/* **************************************************
The following is my proposed solution, which works
************************************************** */
else
{
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mContext->mViewFramebuffer);
}
#else
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mContext->mViewFramebuffer);
#endif
#if GL_EXT_discard_framebuffer
// Framebuffer discard is only supported on devices running iOS 4+
if(mCurrentOSVersion >= 4.0)
{
GLenum attachments[] = { GL_COLOR_ATTACHMENT0_OES, GL_DEPTH_ATTACHMENT_OES, GL_STENCIL_ATTACHMENT_OES };
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 3, attachments);
GL_CHECK_ERROR
}
#endif
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mContext->mViewRenderbuffer);
GL_CHECK_ERROR
if ([mContext->getContext() presentRenderbuffer:GL_RENDERBUFFER_OES] == NO)
{
GL_CHECK_ERROR
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"Failed to swap buffers in ",
__FUNCTION__);
}
}
It seem to me that the reason when FSAA is on the device works is because of this:
Code: Select all
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, mContext->mViewFramebuffer);
However, in the original code, if FSAA is off, it seems to me that the framebuffer isn't selected, and as a result there's unpredictable results.
I find it odd that it works in simulator and not the device, but the simulator is actually running in OpenGL...the GLES API is simply mapped, and so behavior can be different. It might also be different on the various devices and OS versions, I don't know - I only have the iTouch device for testing at present.
What I appended was an "else"...if FSAA isn't applied (mNumSamples == 0), then a more standard call to bind the frame buffer is added, and since the entire FSAA processing is within a define, such that it MIGHT not even be compiled, I appended an else to that define with a repeat of the selection of the framebuffer, as in:
Code: Select all
#if GL_APPLE_framebuffer_multisample
if(mContext->mIsMultiSampleSupported && mContext->mNumSamples > 0)
{
glDisable(GL_SCISSOR_TEST);
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, mContext->mFSAAFramebuffer);
GL_CHECK_ERROR
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, mContext->mViewFramebuffer);
GL_CHECK_ERROR
glResolveMultisampleFramebufferAPPLE();
GL_CHECK_ERROR
}
else
{
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mContext->mViewFramebuffer);
}
#else
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mContext->mViewFramebuffer);
#endif
An I know I'm nitpicking here, because on the device the FSAA doesn't affect frame rates much, so having it on is likely a benefit worth having.
My point, however, is that I (and as a result likely many other qualified developers trying this out on the phone) would have to spend a few days figuring out why, and maybe giving up on Ogre (as I nearly did)....I reasoned that it wasn't likely a serious problem, just elusive at first.
I wouldn't have had the problem if FSAA were defaulted to 2, but that's not a solution.
I'd propose this code if I knew where or how, but I'm not studied on the engine design sufficiently to know of there's a reason my solution isn't correct...it might be something else that left the buffer unattended, where this function expected the framebuffer to be intact, and is intact under other platforms.
If the appropriate members already have an eye on this point, I'm happy to leave it there - and I'm curious to learn if I'm way off base, or close to correct.
