GLSL shaders

To generate the runtime for shaders built with GLFX, you have to explicitly enable the GLFX service because Protobuild will by default generate the runtime for MojoShader built shaders (which are handled differently). To do that instead of just running mono Protobuild.exe you should run mono Protobuild.exe -enable GLFX. If you run into any issues let me know :slight_smile:

Thanks for the advice on that JJagg . What version of OpenTK are you using . Running protobuild with -enable GLFX and attempting to build MonoGame.FrameWork.MacOS gives me these compile errors.

It’s not using MonoMac/OpenTK, but the DesktopGL path which uses SDL for windowing (and input) and custom OpenGL bindings. You probably need to explicitly generate the DesktopGL version if it’s trying to generate MonoMac by default. I’m not sure if that will just work though, I don’t have a Mac :confused:

Thanks for the feedback on this Jjagg. Bringing stuff over from windows to Mac I’m currently facing the challenging of porting some of my bigger hlsl shaders to glsl now. Some of the more elaborate hlsl shaders have proven to be a bit of a challenge. Any suggestions on how one could do this more reliably ? Is re-writing the hlsl shader to glsl the best choice ? In doing this conversion from hlsl-glsl is there any gotchas deviation or difference in what is specified in the shading language here:

There are some tools around to do the translation for your. You’d need to add the effect syntax after that. I prefer doing it by hand using find-replace (float → vec, frac → fract, lerp → mix…), that should handle most things really.

It’s just standard GLSL, but with the effect syntax available.

It’s not using MonoMac/OpenTK, but the DesktopGL path which uses SDL for windowing (and input) and custom OpenGL bindings. You probably need to explicitly generate the DesktopGL version if it’s trying to generate MonoMac by default. I’m not sure if that will just work though, I don’t have a Mac

@Jjagg, any guidance or pointers to material on how I can do this ? I’ve made some good progress with the changes to my shaders but I think Im hitting some runtime issues now which appear could be related to this.

Ok, it turns out it was not this which caused the major issues. I got this all working in the end but there was some things I had to change to make this work on Mac. I had to change the updateparameterdelegate in ConstantBuffer.GLFX.cs to compile on MAC and then drop a new version of MonoGame.Framework. I then had issues when I tried to compile my custom model skinning processor on my Mac with the pipeline tool and noticed the runtime did not work. It turns out the issue was due to this in my shader:

I have a mat4 array in my effect that I use for the bones for my model for animation which seems to have been the causing all my problems at runtime. The inputs were not mapping them like the other params did.
I had to make a few changes in the pipeline goodies and the runtime glfx classes to read this bones matrix and after I did that my stuff started to work on my Mac at runtime. It seems the custom effects for my skinning which I rewrote from hlsl to glsl has compiled on the Mac along with the texture, specular and normal maps and work at runtime now at least and my animations seem to be working for my models. I’m doing some more tests on the animation and texturing side of things to see if there are any bugs but so far its great and I am super happy I can get my content compiled and working on the Mac. I have a bunch deferred render effects I need to take through this process as well but I expect this should all just work. Thanks again for this work Jjagg!!

Wow, that’s great news! :slight_smile: Please post back any bugs you find (or even better, fix ;)) either here or in the PR
EDIT: Sorry, I missed your earlier post!

Things are moving along but I’ve having some issues with porting of some my deferred rendering stuff. I’ve trying to wire up some my shaders for which I use to setup/clear and write to GBuffer. Im trying to write the Texture, Normal and Depth using gl_FragData as such:

 gl_FragData[0] = Color;
 gl_FragData[1] = Normal;  #{ERROR: 0:40}
 gl_FragData[2] = Depth;    #{ERROR: 0:41}

But on runtime getting shader compile errors in Shader.OpenGL.cs

ERROR: 0:40: Index 1 beyond bounds (size 1)
ERROR: 0:41: Index 2 beyond bounds (size 1)

I think these are due to the gl_FragData being size 1 and not 3. @JJagg, any ideas how I can write this data in FragShader ? I typically need to clear the GBuffer, Write to it and need an output from the FragShader for Texture, Normal and Depth.

UPDATE: It might be related to something happening on the device when setting multiple render targets. I get the error below when I set 3 render targets with …GraphicsDevice.SetRenderTargets(_renderTargetBinding.ToArray())

In debug it simply crashes when doing PlatformApplyRenderTargets(). It guessing its something happening {or not happening} when attempting to do attachments for the fragdata. I.m testing this on iPhone 7 simulator, can I set multiple render targets for iOS ? Any thoughts on this one ?

Can you check what the parameters to the GL call that fails are? We should be able to figure out what enum value is wrong and what it should be.
I hope I can help a bit, but I’ve never done MRT and I can’t test iOS because I don’t have a Mac :confused:

Yeah sure, below is a screen. Note the params to GL in the watch window:

From glFramebufferTexture2D

GL_INVALID_ENUM is generated if attachment is not an accepted attachment point.

That seems to be the only thing that could be causing the crash. The value of the attachment when the crash happens is GL_COLOR_ATTACHMENT1 which should be valid. I don’t know what ‘an accepted attachment point’ means exactly…

This certainly will help JJagg and sent me in a direction now. Thank you for this and also prompt reply. I’m taking a look at this now and trying to dig in a little further.

UPDATE: I think I figured this out now, and might just be running into something not supported in GLES 2.0. I don’t think this will be possible with GLES 2.0 actually, maybe 3.0 but from what I can see this might not be possible with the way I have had my existing shaders defined.

Java and C# are relatively different in comparison.

Just wanted to point out that java is very similar to c# more so then c++.
If you know c# you practically already have learned java.

I was using java before c# came out then jumped ship c# provides more flexability pinvokes unsafe ect.
Some basic things are different like the way base and super work in java vs base in c# and a few other minor things. However code java is extremely similar to c#.

You could easily get a program running in no time at all in java and feel like your in very familiar territory, if you already know c#.

1 Like


I was also looking to implement GLSL shaders in monogame as the default shader language rather than HLSL, just for the sake of portability, but I can see this is not available.

I’ve read somewhere that the current transpiler HLSL->GLSL used in the content pipeline may not work well when GLSL is missing features from HLSL.

Can someone with good knowedge/experience provide an insight of the current state of the art?
What are the long term plans?

Thanks :slight_smile:

Not much development here lately, so the steps you need to take are still the same as explained in this thread. Recommended steps:

  1. Fork MonoGame and clone your fork in case you haven’t yet.
  2. Add my fork as a remote: git remote add jjagg
  3. Fetch the GLFX branch. git fetch jjagg glfx
  4. Check it out git checkout glfx
  5. Run Protobuild and enable the GLFX service: [mono] Protobuild.exe -enable GLFX.
  6. Build your shaders with the GLFX target. Check out the SpriteEffect shader in my PR for the syntax (PR. Only old GLSL syntax works for now due to parsing difficulties.
  7. Run your game as usual. There are some errors in my branch, check out comments in the PR for some fixes.

You’re welcome to open PR’s on my branch if you want to contribute. It might get merged soon so you can send PRs to the MG repo directly. Feel free to ask me anything if you run into issues or want to help out.

It generally works pretty well. So if you’re just doing this for portability, I don’t recommend digging into the direct GLSL stuff :stuck_out_tongue: The GLFX branch was pretty quickly implemented and there are probably more issues with it than the automatic translation.

While it would be nice to support GLSL directly (or some dialect to make it fit better into MonoGame), this is a pretty low priority issue. Some better tooling might help speed up the process of supporting GLSL (like the vulkan stuff) because optimization is currently the most difficult thing in supporting GLSL shaders.

Update on the Multiple Render Target on iOS with the glsl issue I had above:

Revisiting this turns out its due to the Graphics Context being constructed for GLES2.0

I changed this number above {in red} to 3 [GLES 3.0] and Multiple render Targets appear to function now as well with glsl compiled shaders for iOS {iPhone /iPad}.


1 Like


I’m trying to compile and run the 2mgfx program with the GLFX target. I’ve followed the instructions, but when I run the 2MGFX with a shader to compile, I get the following error:

Unable to find an entry point named ‘glslopt_initialize’ in DLL ‘glsl_optimizer.dll’.
Unexpected error compiling ‘o:test.fx’!

any ideas why this is happening? Is there a precompiled windows binary anywhere?

Just in case, MD5 is glsl_optimizer.dll 2cfe83111201dbe25856519113b93252


I don’t remember if I actually tested this on Windows :confused: Maybe there are issues with the native dll. I don’t have time to look at this atm. If you want to try to build it yourself, you can check out the MG fork of glsl-optimizer. It has some changes so it supports PInvoke, maybe the windows binary was compiled without these changes. Repo is at

thanks for the answer.

I found that actually contains a working binary dll in the repo.

1 Like