OpenWindow() misbehaves with hints?

anonymous wrote on Wednesday, October 24, 2012:

Release 2.7.6 64-bit… Now this is pretty strange…

I recently added those OpenWindowHint() calls:

glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3)
glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 2)
glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
glfw.OpenWindowHint(glfw.OpenGLForwardCompat, 1)

On an Intel GPU (HD Graphics 4000 with May 2012 driver supporting GL 3.3 /
GLSL 330) OpenWindow() fails and returns 0 (tested with hints for 3.3 as
well). BUT *without* these hints, however, GLFW creates a proper core-
profile, version 3.3 context!

On an nVidia GPU (GeForce GT 640M LE with a recent driver supporting GL 4.2 /
GLSL 420), OpenWindow() creates a proper core-profile, but version 3.2
context. Without hints, a core-profile, version 4.2 context.

Now, the GLFW reference.pdf states: The GLFW_OPENGL_VERSION_MAJOR and
GLFW_OPENGL_VERSION_MINOR hints specify the OpenGL version that the created
context must be compatible with, not the exact version to use. It is therefore
perfectly safe to use the default of version 1.1 for legacy code and you will
still get backwards-compatible contexts of version 3.0 and above when
available.
So as per this, it would be highly desirable if I could get a 4.2
context here even if 3.3 is specified as the desired minimum. How can this be
achieved?

Now, you might wonder - why should I even bother with these hints if the
system seems to automatically select the perfect context without any hints?

Mac OS X is the main reason. I have an MBP with a GeForce 330M and some
integrated graphics chip, OpenGL Monitor’s “renderer info” states that core
profile 3.2 is available. However, when running my app without hints, GLFW
(or OS X) defaulted to creating a GL 2.0 profile instead. My desired minimum
version as mentioned is 3.2 so my code wouldn’t work in 2.0. I have not yet
tested whether OpenWindowHints() for 3.2 work under OS X (kinda switching
back and forth between development locations & machines) but will do so
later.

However, as far as I can tell, in 2.7.6 OpenWindowHint() does not seem to
act according to its own specs on a 4-months-old Win7 64-bit machine with two
current-gen GPUs and up-to-date drivers. For Intel HD, it fails to create a
core profile with a version positively supported by the driver (and working
fine when not using Hints), for nVidia GeForce it fails to create a maximum-
version core profile and interprets “minimum desired version” as “maximum
permissible version”.

Any insights? If Hints turn out to work as expected under OS X, I’ll be happy
to use them only under OS X. Still, I’m slightly surprised how off my results
are from what one would expect as per the spec :wink:

anonymous wrote on Wednesday, October 24, 2012:

Also, it would be really neat if one could just
glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) and skip the
other hints (versions and so forth) and have it work auto-magically, but
doing that, OpenWindow() seems to fail on both GPUs.

anonymous wrote on Wednesday, October 24, 2012:

Update: nVidia Quadro 5010M (Win7) behaves like the GeForce, which makes
sense since they’re essentially the same driver - Hint() misbehaves in that
it creates a strict 3.2 context instead of the 4.2 created without Hint().

anonymous wrote on Wednesday, October 24, 2012:

Update: under Mac OS X, with a GeForce GT 330M - thankfully! -
OpenWindowHint() works as required and creates the requested 3.2 core
profile context, whereas without the hint it would create a 2.0 legacy
context. So that’s good.

Though of course, even with that status as-yet, we still can’t predict whether
in the future (whenever Apple finally *does* decide to update their GL
version - like that’s even remotely thinkable…), OpenWindowHint will once
again, undesirably, interpret “minimum desired version” as “maximum
permissible version” under OS X too…

elmindreda wrote on Wednesday, October 24, 2012:

GLFW doesn’t choose which version of OpenGL the context ends up with; it
simply passes on the choices you’ve made to the context creation
API
. The
spec of glfwOpenWindowHint never claims to return the highest version
available when asked for a specific, non-1.0 version, only that it be a
version compatible with the one you’re requesting. This, in turn, is all GLFW
can ask of the context creation API.

There is nothing to be gained from getting a context of a version higher than
you need, so ask for what you need. If your code uses OpenGL 3.2, it won’t go
faster if the context is OpenGL 4.3.

Also, no other version of OpenGL could provide both core profile, forward-
compatibility and all the functionality of the requested version. If you
remove those constraints, you will likely get a version greater than 3.2 on
both Windows machines (more on OS X later).

Intel is a relative newcomer to modern OpenGL, so it may be that they haven’t
properly implemented forward-compatible contexts yet. If you don’t need
forward-compatibility, you can leave that hint off on OS:es other than OS X
(where it’s sadly required) and see if that helps the current version of the
Intel driver.

There is very rarely a reason to use forward-compatibility on anything except
OS X, as the only thing it does is disable functionality deprecated by that
version of the OpenGL spec. Its only other use is to ensure that your code
will run on the core profile of future versions, where features now deprecated
have been removed.

If you only set the profile hint and not the version hints, you are requesting
an OpenGL 1.0 core profile context, which is nonsensical. Context profiles
were defined starting with OpenGL 3.2 and GLFW will refuse even to attempt
creating a context with a specific profile if the version is less than 3.2, as
the driver would just throw an error anyway if it did.

The reason GLFW cannot just create a 3.2 context by default on OS X is that,
since the only available variant is both core profile and forward-compatible,
all legacy functionality is missing. The window hint default in GLFW is a
version compatible with OpenGL 1.0. Hence the requirement to show GLFW that
you know what you’re asking for.

When Apple adds a newer OpenGL version, it will likely be another jump to an
isolated version, like forward-compatible, core profile OpenGL 4.2, and again
GLFW would be unable to use that by default, as it won’t provide API
compatibility with either OpenGL 1.0 or its specific 3.2.

I hope this addresses all the issues you wrote about.

anonymous wrote on Thursday, October 25, 2012:

Thanks for the detailed reply! Definitely gave me a better understanding of
things. My code now first does a hintless WindowOpen(), if then the GL
version is lower than 3.2 it closes the window, does a glfw re-init, adds the
core 3.2 hints and tries again. Seems an OK way to get the newest GL version
both on Windows and Mac for now.

There is nothing to be gained from getting a context
of a version higher than you need, so ask for what
you need. If your code uses OpenGL 3.2, it won’t go
faster if the context is OpenGL 4.3.

Yes but I will selectively activate features based on higher GL versions if
they’re available, while degrading gracefully when they’re not. So the context
I request really should be the highest-version the GPU driver is possibly
capable of. Otherwise, sure, I could just request a 3.2 context across
platforms and be done with it.

elmindreda wrote on Thursday, October 25, 2012:

That will definitely work, but on OS X you’ll get a window (and possibly mode
setting) flash by before the second glfwOpenWindow call succeeds, as the
window is created before the context.

The __APPLE_CC__ macro, which is only defined on OS X, may be useful
here.