jeske's picture

GameWindow and OpenGL hardware compatibility?

I'm just getting started learning OpenGL and OpenTK. I hacked up a quick example which seems to be working okay. I used GameWindow, and I can see the convenience. My simple app works with the same binary on my win7/nvidia desktop and my MBP retina laptop.

http://www.codeproject.com/Articles/798054/SimpleScene-d-scene-manager-i...
https://github.com/jeske/SimpleScene

I'd like some advice on handling device compatibility. My goal is the widest device compatibilty, so I targetted GL2.2 GLSL120. (and also because GL2.2 is the best I got on the Mac with OpenTK because of the Carbon stuff?)

However, my code doesn't work on the Intel HD 4000. Apparently they don't support some GL shader extensions *unless* I ask for GL 3.0. However, other parts of my code have to change to use GL3. (Because my code is written for GL2.2, it uses the legacy MatrixMode stuff).

I can abstract out the different OpenGL activities into some kind of HAL, implementing it once per GL version. However, I'm confused about how to handle this given the way the OpenGL version is bound by the GameWindow. It means I have to know my GL version before creating a gamewindow. Also, I'll need to store all of my program state outside of my gamewindow if I want to switch GL context versions without restarting.

What do folks do? pick an OpenGL version before making a GameWindow and never change it? Tear up and down gamewindow? stop using GameWindow?

Also, I would like to get live-resize of the window... but as far as I can see, NativeWindow doesn't support this. Do I have to go around NativeWindow, or fix it?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture
Quote:

I'd like some advice on handling device compatibility. My goal is the widest device compatibilty, so I targetted GL2.2 GLSL120. (and also because GL2.2 is the best I got on the Mac with OpenTK because of the Carbon stuff?)

However, my code doesn't work on the Intel HD 4000. Apparently they don't support some GL shader extensions *unless* I ask for GL 3.0. However, other parts of my code have to change to use GL3. (Because my code is written for GL2.2, it uses the legacy MatrixMode stuff).

This is a policy decision by Apple (OpenTK 1.1.2+ is Cocoa all the way, so there is no limitation on that part.)

Compatibility contexts are limited to GL 2.1, so you have to use a core profile to access higher functionality. Unfortunately, this means you have to decide between using legacy functions and being limited to GL 2.1, or dropping all legacy functions and being able to use higher functionality. If you decide to go for the latter, I'd suggest switching to OpenTK.Graphics.OpenGL4 to avoid using unsupported functionality by mistake.

Note that this limitation does not exist on Windows or Linux[1], were compatibility contexts support the same functionality as core contexts.

Quote:

I can abstract out the different OpenGL activities into some kind of HAL, implementing it once per GL version. However, I'm confused about how to handle this given the way the OpenGL version is bound by the GameWindow. It means I have to know my GL version before creating a gamewindow. Also, I'll need to store all of my program state outside of my gamewindow if I want to switch GL context versions without restarting.

If you are aiming for maximum compatibility, then you need some sort of HAL anyway. This is an unfortunate reality in OpenGL[2]. See for example here for one possible approach (this one is abstracting the EXT and Core versions of renderbuffer objects.)

So how do you construct the GameWindow? It's simpler than it looks: ask for the minimum version that will cover the requirements of your project. If that is a compatibility 3.1 profile, then ask for that. If it's a core 4.0 profile, then use that. OpenTK will pass your request to the driver. If, for any reason, the driver fails to construct a context with the specified attributes, OpenTK will relax them and try again, until it succeeds. (Context construction will always succeed in the end, as long as a valid driver is present.)

Once the window is constructed, you need to check the actual OpenGL version for your driver using GL.GetString(StringName.Version) or GL.GetInteger(GetPName.Major/MinorVersion). At this point, you can initialize your HAL using this version number, or take some other action if the version is not sufficient (e.g. instruct the user to upgrade his drivers.)

Edit: Note that in the general case you *cannot* know the maximum supported OpenGL version without first constructing an OpenGL context. This chicken-and-egg problem is an inherent flaw of OpenGL, i.e. you would face the same issue even if you used a different toolkit to construct the context, such as WGL or SDL.

Quote:

Also, I would like to get live-resize of the window... but as far as I can see, NativeWindow doesn't support this. Do I have to go around NativeWindow, or fix it?

I guess you mean redrawing the window while the user is resizing? This is supported. Check out the threaded rendering example for the correct cross-plaftorm solution.

(Platform-specific solutions also exist, but they suffer from various disadvantages.)

[1] Technically, the llvm (software) backend for Mesa3d limits compatibility contexts to 3.0, but it's unlikely you'd ever encounter this limitation.

[2] I have high hopes for OpenGL 5.0, which is expected to be released in Siggraph 2014.

Frassle's picture
the Fiddler wrote:

[2] I have high hopes for OpenGL 5.0, which is expected to be released in Siggraph 2014.

khronos wrote:

Hear how OpenGL ES and OpenGL are evolving to meet the needs of next-generation 3D applications, providing lower overhead and greater graphics richness on mobile and desktop platforms.

Probably just a preview, don't get your hopes too high.

jeske's picture
the Fiddler wrote:

Note that this limitation does not exist on Windows or Linux[1], were compatibility contexts support the same functionality as core contexts.

My program works fine on MacOS and Windows/Nvidia.. I ask for GL 2.2, use GLSL120 with GL_EXT_gpu_shader4 and GL_EXT_geometry_shader4, both of which are available on MacOS and Windows/NVidia.

The problem is on Windows Intel HD4000 driver. Specifically a Fujitsu Lifebook with a signed older version of the Intel driver. OpenGL-ARB says GL_EXT_gpu_shader4 is an OpenGL 2.0 extension, but if I'm understanding the problem correctly, the Intel driver only provides the extension for GL contexts version 3+.

I added some code to use the "legacy" method to check for the extension, maybe this will work? I don't have access to this hardware at the moment.

GL.GetString(StringName.Extensions).ToLower().Contains("gl_ext_gpu_shader4")

the Fiddler wrote:

So how do you construct the GameWindow? It's simpler than it looks: ask for the minimum version that will cover the requirements of your project. ....Once the window is constructed, you need to check the actual OpenGL version for your driver using GL.GetString(StringName.Version) or GL.GetInteger(GetPName.Major/MinorVersion). At this point, you can initialize your HAL using this version number, or take some other action if the version is not sufficient (e.g. instruct the user to upgrade his drivers.)

Okay, except I think you meant "maximum" not "minimum" right?

I'd ask for the maximum GL version I've coded for, let OpenTK downgrade to an available version, then check the version and slip in the proper HAL. (downgrading as necessary)