Imgui: sdl_opengl3_example requires GL 3.2 but shaders require GLSL 3.30

Created on 28 Nov 2017  路  14Comments  路  Source: ocornut/imgui

In sdl_opengl3_example/main.cpp the OpenGL context version is set to 3.2:

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);

However, in the vertex and fragment shaders, GLSL version 3.30 is required:

#version 330

According to Khronos wiki, OpenGL 3.2 should be associated with GLSL 1.50: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#OpenGL_and_GLSL_versions

I've got no knowledge of GLSL, but changing #version 330 to #version 150 makes it run with MESA_GLSL_VERSION_OVERRIDE=150 set.

backenbinding opengl

Most helpful comment

@stfx The TL;DR version: Because Apple said so, no real legitimate reason.

The long version: Apple's drivers are really strange in that they have three totally separate paths in them: 2.1 Compat, 3.2 Core, and 4.1 Core. I'm not talking about specifications, I'm talking literal separate code paths in OpenGL.Framework where each context version gets a completely 100% different pile of code in them. If you look up backtraces for macOS driver crashes you'll see lots of call stacks where C functions are even namespaced like glDrawElements_GL3Exec.

So while extension lists for certain _specifications_ are supported, the actual set of features supported by each _context_ is entirely different, and the number of contexts is limited to those three (AFAIK).

The best part is that the limitations of all three are simultaneously very restricted and very loose at the same time. A good example of the former is GLSL, where the GLSL version _absolutely must match_ to the letter. If you do anything other than 150 on 3.2 Core, 410 on 4.1 Core, or 110/120 on 2.1 Compat, it _will_ crash. However, in the latter scenario, you'll find that even 2.1 Compat has support for stuff like ARB_framebuffer_object, ARB_draw_instanced, and even ARB_instanced_arrays! So on macOS if you want to target 3.3, you basically can since 3.2 Core has pretty much all the extensions you'll care about while also targeting pre-Mavericks machines, with the exception of GLSL 3.30 extensions like ARB_explicit_attrib_location and ARB_shader_bit_encoding (the former being really easy to replace and the latter not being terribly important unless you like type casting a whooole lot).

It's very confusing and anyone at Apple that would have ever cared about making this clearer has long since moved on to either Metal or just a different company entirely.

All 14 comments

I suggest that this is fixed by bumping the version to OpenGL 3.3, which seems to be the de-facto minimal version for modern OpenGL. There should also be the forward compatibility flag set and the shaders should use #version 330 core.

Thanks @jiri for your PR.
Would doing as suggested by @piernov? If macOS accepts GL 3.20 + GLSL 1.50 we would probably want to aim for the lowest version?

I am summoning @flibitijibibo in this thread, who doesn't work on this project but since he is sympathetic toward dear imgui maybe he can share some of his empirical knowledge regarding Mac/Linux compatibility of OpenGL? Thanks Ethan :)

Definitely aim for GL 3.2 Core + GLSL 1.50. Linux doesn't care about this too much thanks to overrides but macOS OpenGL profiles are kind of a horrid mess and require _very_ specific versions for both the context and the #version in order to work at all. So I would just change it to #version 150 and it should work for both Mesa and macOS.

EDIT: Also for macOS you either have 3.2 or 4.1, nothing in between.

I've tweaked the versions in my PR to reflect this, so it's now OpenGL 3.2 + GLSL 1.50, which works fine for me on macOS. Thanks for the info!

Thank you @flibitijibibo !
One more question: since the imgui_impl_xxx file contains the shaders and those can be grabbed by users into their project. Do you know if #version 150 shaders would cause problems if people uses a GL 3.3+ profile?

I believe Mesa is okay with mismatched versions, but macOS definitely will complain if the versions aren't exactly aligned across the board, so each context version gets to have its own shaders too :/

OK I think we could aim at adding a const char* glsl_version_string = "#version 150" to the init function of those backend and have the code create the shader string accordingly then.

Also for macOS you either have 3.2 or 4.1, nothing in between

@flibitijibibo Can you explain why you can not have opengl 3.3 on macOS in more detail as I did not find any info about that on the internet? Did you make that statement because macOS 10.7.5. supports up to 3.2 and only macOS 10.9 added support for 3.3 and 4.1 as can be seen on https://developer.apple.com/opengl/OpenGL-Capabilities-Tables.pdf#page=24 ?

@stfx The TL;DR version: Because Apple said so, no real legitimate reason.

The long version: Apple's drivers are really strange in that they have three totally separate paths in them: 2.1 Compat, 3.2 Core, and 4.1 Core. I'm not talking about specifications, I'm talking literal separate code paths in OpenGL.Framework where each context version gets a completely 100% different pile of code in them. If you look up backtraces for macOS driver crashes you'll see lots of call stacks where C functions are even namespaced like glDrawElements_GL3Exec.

So while extension lists for certain _specifications_ are supported, the actual set of features supported by each _context_ is entirely different, and the number of contexts is limited to those three (AFAIK).

The best part is that the limitations of all three are simultaneously very restricted and very loose at the same time. A good example of the former is GLSL, where the GLSL version _absolutely must match_ to the letter. If you do anything other than 150 on 3.2 Core, 410 on 4.1 Core, or 110/120 on 2.1 Compat, it _will_ crash. However, in the latter scenario, you'll find that even 2.1 Compat has support for stuff like ARB_framebuffer_object, ARB_draw_instanced, and even ARB_instanced_arrays! So on macOS if you want to target 3.3, you basically can since 3.2 Core has pretty much all the extensions you'll care about while also targeting pre-Mavericks machines, with the exception of GLSL 3.30 extensions like ARB_explicit_attrib_location and ARB_shader_bit_encoding (the former being really easy to replace and the latter not being terribly important unless you like type casting a whooole lot).

It's very confusing and anyone at Apple that would have ever cared about making this clearer has long since moved on to either Metal or just a different company entirely.

There is one advantage that ImGui uses 3.3 profile.
3.3 profile supports texture siwizzling[1], which enables us to use GetTexDataAsAlpha8() instead of GetTexDataRGBA32() without modifying current shaders.

[1] https://www.khronos.org/opengl/wiki/Texture#Swizzle_mask

@y-fujii That's an interesting feature, thanks for posting that!
For imgui examples, I think we need to aim at maximum compatibility. People who really aims at optimal GPU performance can always figure out a way (this one or another among many), Getting those simple examples to work for everyone everywhere has been sufficiently difficult.

(And actually, as flibitijibibo posted, the 3.2 Core profile of OSX may even support that. According to https://developer.apple.com/opengl/OpenGL-Capabilities-Tables.pdf since macOS 10.8.5 the 3.2 profile include the texture_swizzle extension.)

I'm closing it, applied the initial fix suggested to both both SDL and GLFW examples to use OpenGL 3.2 Core + GLSL 150.

What I didn't do: expose the GLSL version string to the imgui_impl_xxx API. Will wait until someone can confirm and repro a problem with using GLSL 150 with their driver/version of GL.

Thanks everyone for helping with it!

FYI
I have added a parameter to ImGui_ImplGlfwGL3_Init(), ImGui_ImplSdlGL3_Init() etc to override the GLSL version string.

FYI in fff014d I have

  • Added support for pre-130 GLSL in imgui_impl_opengl3.cpp by parsing the version string.
  • Made the examples apps default to GL 3.0 + GLSL 130 unless running on a Mac. (from the previous GL 3.2 + GLSL 150)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bizehao picture bizehao  路  3Comments

dowit picture dowit  路  3Comments

SlNPacifist picture SlNPacifist  路  3Comments

the-lay picture the-lay  路  3Comments

ILoveImgui picture ILoveImgui  路  3Comments