Context:
By default jme runs the compatibility profile. That means the driver tries it’s best to work with frankenstein shaders containing multiple glsl version statements and much more.
This is a pitfall for devs as it can lead to driver-specific (mis-) behavior.
Furthermore it may swallow compilation warnings or errors and just assume stuff, which may be undesired.
Core Profiles for specific versions, on the other hand, can be seen as regular APIs. Some stuff got deprecated in later versions, new things have been added, but you cannot use statements, that are unsupported for that particular version. Compilers are also more strict there typically, so it helps writing clean GLSL Shaders. Therefor every developer should enable the core profile on the minimum supported version.
This is even more relevant on Mac OS X, where the compat profile only supports OpenGL 2.0 but a core profile for 3.1 is available (and on more recent Macs an even higher version, iirc).
There is GLSLCompat.glslib that e.g. allows our OpenGL 3.1 based PBR Shaders to run on OpenGL 2.0, but that’s always a workaround and the native version should be preferred, which needs the core profile on macOS.
Problem:
Setting the Core Profile currently happens without feedback. It’s just setting a string via the AppSettings and that string contains both the Rendering Backend as well as the OpenGL String (so we basically use substring for that, same for the custom rendering backends that are prepended via CUSTOM
).
Reference:
While this is good to save (like the appsettings will then contain the openGL version), this only really works when having an installer detect the core profiles beforehand.
You can basically only try to wrap the whole Application (and especially start()) into try-catch and brute force every string constant AppSettings offer.
Imagine you want to build a bleeding edge application using OpenGL 4.5 features, but then there’s this guy with an OpenGL 3.1 Laptop.
You basically have 3 options:
- Compatibility Profile
- Only use 3.1 Features (and maybe add 4.5 replacements to GLSLCompat.glsllib, where possible)
- Screw that laptop guy
How about an option 4? You probe the available profiles and then selectively disable/replace some shaders to keep core profiles where possible. Chances are, the more modern features are only required for advanced techniques but a simple baseline can be produced that only requires e.g. OpenGL 3.1
Even if not, having a better way to handle not-existant core profiles to display an error dialogue would be cool.
Proposal:
I am open to hearing your ideas, but from a quick thought, I could come up with two ideas:
-
Application#setCoreProfile throws InvalidOperationException
. This would entail having proper context restarts and would enable an in-game setting to change the renderer as well as the profile, which is helpful to debug issues as well.
It may be hard to achieve with the current code structure, though, since typically renderers open the whole context (e.g. the window) and then stay. -
A callback or rather
Function<List<Profiles>, Profile>
app.chooseCoreProfile((profiles) => {
if (profiles.contains(Profile.OPENGL44) {
return Profile.OPENGL44;
} else if (profiles.contains(Profile.OPENGL31) {
app.openGL31Compat = true; // user supplied field to handle 3.1, could also be replaced by like App.getActiveCoreProfile()
return Profile.OPENGL31;
} else {
app.showDialog("A minimum of OpenGL 3.1 is required to run this Application");
return null;
}
});
What are your thoughts? Ideas? Don’t see any use? etc.