iOS Multisampling Broken on OpenGL ES 2.0


#1

Multisampling doesn't work on devices without OpenGL 3.0 (e.g. the iPhone 5). It's a trivial fix though. In juce_OpenGL_ios.h, this:

 

           #if defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
            glBlitFramebuffer (0, 0, lastWidth, lastHeight, 0, 0, lastWidth, lastHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
           #else
            glResolveMultisampleFramebufferAPPLE();
           #endif

should be this:

           #if defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
            if (version == OpenGLContext::openGL3_2)
            {
                glBlitFramebuffer (0, 0, lastWidth, lastHeight, 0, 0, lastWidth, lastHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
            }
            else
           #endif
            {
                glResolveMultisampleFramebufferAPPLE();
            }

(Add a member variable for the version.)

Then everything works fine.


#2

Cool, thanks for the heads-up, we'll add that asap!


#3

juce_OpenGL_ios.h:151:17: Use of undeclared identifier 'version'

 


#4

Sorry, seems like I didn't correctly compile this when I thought I was testing it, and the OP's code seems to be broken in other ways too.

@cbrown - did you actually compile this, as glResolveMultisampleFramebufferAPPLE doesn't seem to be available on newer versions of the SDK... Are you sure you actually tested it?


#5

I have definitely thoroughly tested the changes. They compile and run on both hardware and simulator. They definitely produce the expected results (multisampling) on devices that don't support glBlitFramebuffer.

I thought it would suffice to say "Add a member variable for the version.", but in addition to the change in the OP, add this:

   OpenGLVersion version;


After this:

   bool useDepthBuffer, useStencilBuffer, useMSAA;

And add this:

, version(version)

After this:

useStencilBuffer (pixFormat.stencilBufferBits > 0), useMSAA (multisampling)

glResolveMultisampleFramebufferAPPLE is definitely available in every SDK since 4.0. It's declared in OpenGLES/ES1/glext.h and OpenGLES/ES2/glext.h. Maybe a difference in build settings is preventing you from importing the right headers.


#6

The full diff for my change looks like this:

diff --git a/modules/juce_opengl/native/juce_OpenGL_ios.h b/modules/juce_opengl/native/juce_OpenGL_ios.h
index 378e2af..a53d9f3 100644
--- a/modules/juce_opengl/native/juce_OpenGL_ios.h
+++ b/modules/juce_opengl/native/juce_OpenGL_ios.h
@@ -54,7 +54,8 @@ public:
           depthBufferHandle (0), msaaColorHandle (0), msaaBufferHandle (0),
           lastWidth (0), lastHeight (0), needToRebuildBuffers (false),
           swapFrames (0), useDepthBuffer (pixFormat.depthBufferBits > 0),
-          useStencilBuffer (pixFormat.stencilBufferBits > 0), useMSAA (multisampling)
+          useStencilBuffer (pixFormat.stencilBufferBits > 0), useMSAA (multisampling),
+          version(version)
     {
         JUCE_AUTORELEASEPOOL
         {
@@ -149,11 +150,16 @@ public:
             glBindFramebuffer (GL_DRAW_FRAMEBUFFER, frameBufferHandle);
             glBindFramebuffer (GL_READ_FRAMEBUFFER, msaaBufferHandle);
 
-           #if defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
-            glBlitFramebuffer (0, 0, lastWidth, lastHeight, 0, 0, lastWidth, lastHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-           #else
-            glResolveMultisampleFramebufferAPPLE();
-           #endif
+#if defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
+            if (version == OpenGLContext::openGL3_2)
+            {
+                glBlitFramebuffer (0, 0, lastWidth, lastHeight, 0, 0, lastWidth, lastHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+            }
+            else
+#endif
+            {
+                glResolveMultisampleFramebufferAPPLE();
+            }
         }
 
         glBindRenderbuffer (GL_RENDERBUFFER, colorBufferHandle);
@@ -203,6 +209,8 @@ private:
     int swapFrames;
     bool useDepthBuffer, useStencilBuffer, useMSAA;
 
+    OpenGLVersion version;
+
     bool createContext (EAGLRenderingAPI type, void* contextToShare)
     {
         jassert (context == nil);

This builds perfectly fine with a new, unmodified OpenGL iOS project created via Introjucer. I have been testing this with commit 7a370a9019f94aed446a45f0ba14b8c65d798fb5.


#7

I see that you've made some related commits. But if that "#ifdef GL_APPLE_framebuffer_multisample" is required for you to compile, you're masking your issue and not fixing anything. Please make absolutely sure that you have an understanding of why glResolveMultisampleFramebufferAPPLE wasn't available, fix that issue, then test multisampling on a device that doesn't support OpenGL ES 3 and ensure that you do actually get the expected results. See this page for a listing of such devices: https://developer.apple.com/library/ios/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/OpenGLESPlatforms/OpenGLESPlatforms.html


#8

Your issue is probably related to assumptions like the one in this chunk of directives in juce_opengl.h:

#elif JUCE_IOS
 #if defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
  #include <OpenGLES/ES3/gl.h>
 #else
  #include <OpenGLES/ES2/gl.h>
 #endif

ES3 being available when targetting iOS 7 and above is NOT a valid assumption. It depends on hardware. You need to always include the ES2 extensions as well and decide when to use them at run-time.

 

Edit: Sorry for the quadruple post. I should have just appended to one. I don't see any way to delete them now though.