[Solved] iOS GLES 3.0

Since there are many newer iOS devices that support GLES 3.0, could someone outline the steps to upgrade the iOS framework to use it?

This should allow MRT among other features, right?

Thanks!

I tried just changing the EAGLRenderingAPI and that alone didn’t work. I imagine I will need to change the IOpenGLApi among other things too. I’m not super familiar with how the API is used yet.

@dellis1972 didn’t you just get a PR merged that makes mobile use GLES 3.0 if it’s supported? Or was that just Android?

As far as I can tell it looks like that was just for Android.

I’m getting error 1286 from PlatformClear:

GL_INVALID_FRAMEBUFFER_OPERATION, 0x0506
Given when doing anything that would attempt to read from or write/render to a framebuffer that is not complete.

Unhandled Exception:
Microsoft.Xna.Framework.Graphics.MonoGameGLException: GL.GetError() returned 1286
at Microsoft.Xna.Framework.Graphics.GraphicsExtensions.CheckGLError () [0x00030] in <2ed079e9f5554c6fbbc5b074c463b96c>:0
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.PlatformClear (Microsoft.Xna.Framework.Graphics.ClearOptions options, Microsoft.Xna.Framework.Vector4 color, System.Single depth, System.Int32 stencil) [0x0013a] in <2ed079e9f5554c6fbbc5b074c463b96c>:0
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.Clear (Microsoft.Xna.Framework.Color color) [0x0001f] in <2ed079e9f5554c6fbbc5b074c463b96c>:0
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.ApplyRenderTargets (Microsoft.Xna.Framework.Graphics.RenderTargetBinding[] renderTargets) [0x000c5] in <2ed079e9f5554c6fbbc5b074c463b96c>:0
at Microsoft.Xna.Framework.Graphics.GraphicsDevice.Initialize () [0x000d3] in <2ed079e9f5554c6fbbc5b074c463b96c>:0
at Microsoft.Xna.Framewor
k.Graphics.GraphicsDevice…ctor (Microsoft.Xna.Framework.Graphics.GraphicsAdapter adapter, Microsoft.Xna.Framework.Graphics.GraphicsProfile graphicsProfile, Microsoft.Xna.Framework.Graphics.PresentationParameters presentationParameters) [0x001a0] in <2ed079e9f5554c6fbbc5b074c463b96c>:0

I also noticed that OpenGL.iOS tries to open the framework with path /System/Library/Frameworks/OpenGLES.framework/OpenGLES, whereas mine is located within the SDK at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/OpenGLES.framework, but changing this doesn’t seem to make a difference.

EDIT: The error comes from the final clear, even if none of the bits are set. So I’m assuming it really is an issue with the framebuffer, not the clear operation.

OpenGL ES 3.0 is supposed to be backwards compatible, so I’m not sure what the issue is. Is anyone else able to get this working? @Zkylar it seemed like you were able to figure it out in another thread.

I tried adding a CheckFramebufferStatus before the Clear, and it returned GL_FRAMEBUFFER_UNDEFINED. But it did the same thing when using GLES 2.0 too, and that works fine if I remove the check.

Hi jnoyola, I eventually got MRT working for iOS as I mention in this post by changing the “major” version param on GraphicsContext init to “3”. I made this change in GraphicsContext.cs. This is not the only change I had to make because there are a few places where there were namespace usings for GLES 2.0 like this:

using OpenTK.Graphics.ES20;

as you can see here:

I changed these places to use “OpenTK.Graphics.ES30”

When I made this change there were a few other enum changes I had to make due to them not available in the OpenTK.Graphics.ES30 namespace and when I compiled and run my iOS app I can then use multiple render targets.

There may be a more elegant way to target GLES 3.0 via protobuild but I have not checked if thats possible yet. It would be nice because then one does not have to change these by hand. By default the projects seem’d geared towards GLES 2.0 from what I’ve seen

I see, thanks!

This branches off from the codebase back before OpenTK was switched out. Maybe I’ll check out the OpenTK source to see what changes between those namespaces

I think the GL_FRAMEBUFFER_UNDEFINED error was a red herring. This error shows up with both GLES 2.0 and 3.0 when I build the framework in the Debug configuration because that causes additional checks to run that aren’t in Release. I was able to get it to build and run by first trying to load glInvalidateFramebuffer before falling back to glDiscardFramebufferEXT.

The problem is that MRT is still not working. SetRenderTargets now succeeds (with 2.0 this call would fail) but all targets after the first remain black. DesktopGL confirms that my trivial shader should be filling 2 render targets.

hi jnoyola, the branch Im currently getting my goods working on might still need a merge of latest stuff and its still dependent on OpenTK.

I’ve been using JJaggs glfx branch: https://github.com/MonoGame/MonoGame/pull/5354

Ok. I’d prefer to stay off OpenTK to keep everything smaller and to stay in sync with the main develop branch, but I may switch back if I get too frustrated trying to figure out GLES 3.0 myself.

EDIT: I decided to go back to the glfx branch and make the OpenTK updates you mentioned to see if I could learn anything or to at least use for now. Even with that, it now gives a “Shader compilation failed” error if I try to use MRT, but works otherwise. @Zkylar did you run into any issue like that? I wonder if this is similar to the original error I was having without OpenTK, where a pixel shader returning multiple colors just wouldn’t affect the other render targets.

I ran into a few issues whilst migrating to the glfx branch but don’t recall a shader compilation failed one. Where are you getting this error at the moment are you getting this when running your app ? Can you provide more details of what you trying to do in code ? Send me a stack trace at the time of the error or a project snippet / sample recreating the error and I can see if I can spot something.

The error happens on GetShaderHandle within DrawIndexedPrimitives on a trivial shader. It only happens when the pixel shader returns multiple colors. Even if I set multiple render targets but only return one color, the first render target works fine. The same MRT setup also works fine on DesktopGL. Away from my computer right now, but I’ll try to get a minimal repro in a bit.

I must have screwed something up before. I started with a fresh glfx branch and made (what I thought were) the same changes and now it runs without a shader compilation error. I now have both the OpenTK and non-OpenTK frameworks in the same state: it builds and runs with ES 3.0 but only the first render target gets any shading. I’ll work on a minimal repro for this now, and whatever error I have should be agnostic to OpenTK.

@Zkylar Here is a minimal repro. Running DesktopGL on Windows 10, I can see the effect has been applied to both render targets, showing red on the left and green on the right. Running iOS on my iPhone 6s (supports GLES 3.0), I see red on the left and the black background on the right.

Files:

  • MonoGameTest.cs: the game that applies an effect and renders targets to screen
  • Content/Effects/Clear.fx: a simple effect that outputs red to the first render target and green to the second; this has been compiled with 2MGFX.exe /Profile:OpenGL
  • FullscreenQuad.cs: typical implementation

Included NuGet packages:

  • DesktopGL/Android: built from MonoGame/develop
  • iOS: built from Jjagg/glfx after replacing every instance of ES20 with ES30, changing the GraphicsContext major version from 2 to 3, and removing the now unnecessary Ext/Oes/Apple tags from some enums

Spent some time troubleshooting this today and its looking like MRT not working on the latest glfx branch at the moment. I’m digging into it a little more later this week to try find out where a change was made and what different. I have an older source of the branch where it did work so I’m gone run some compares in an effort to try figure it out.

1 Like

That was just android I’m afraid

1 Like

Turns out to get MRT working on iOS again has something to do with this section in GraphicsDevice.OpenGL.cs.

When I remove the conditional ifs for GLES and some other ones down in the project for GLES MRT starts working again. I also had to change DrawBuffersEnum to FramebufferAttachment instead.

1 Like

Brilliant! That was the missing piece.
Here is the commit that I made to upgrade iOS to GLES 3.0 on a clean develop branch.

I don’t know if all my changes were necessary, or if there are some important ones that I missed, but I now have MRT working. Thank you so much!

It would certainly need to be cleaned up a bit if anyone wanted to support automatically falling back to 2.0, but I’m not sure if that’s a common case given that people usually use 3.0 for its exclusive features.

hi, i noticed you have solution for MRT work on IOS GLES3.0. do you know how to solve the problem on android GLES 3.0 ?

I having this issue similar like you, but i try to replace to code that you had. But still same issue.