My Properly-Created OpenGL Context Is Lying To Me.

Started by
4 comments, last by WoopsASword 7 years, 6 months ago

Hi,

I have created an OpenGL context in what I believe is the proper way, but on Linux, basic calls such as `glGetString(...)`, `glGetIntegerv(...)` are returning bogus values/no-ops. Despite this, the context seems to render everything fine. On Windows, I follow the same algorithm and it works perfectly.

Fortunately, since I've been having this problem for such a long time, I've had the opportunity to make some very pretty debug output. In case it isn't obvious, in the following, red is a frame/window, cyan is an OpenGL context, yellow is an API pointer, and violet is the display server handle.

Here is the output on Windows:
[sharedmedia=gallery:images:7659]
The algorithm is as follows:

  • (line 1): Create a basic context on a default frame
  • (lines 3-5): Set the basic context as current, load its API pointer for `wglCreateContextAttribsARB(...)`, unset context.
  • (lines 7-9): Set the basic context as current, call the API pointer to create an attribute context
  • (lines 11-13): Set the attribute context as current, and set it up (including loading its API pointer, which happens to be the same; we don't use it ever, though).
  • (line 15): Set attribute context as current in preparation for main loop.
  • (line 15.5): [Main loop]
  • (line 16): Unset the attribute context.
  • (lines 18-19): Cleanup.

Now, I try to do something very similar on Linux:
[sharedmedia=gallery:images:7658]
Unfortunately, it doesn't work. Notice the error after line 12. At that point, I called `glGetString(...)` and it returned null. This should not be possible. A context is bound (line 11). Crucially, there is no GL error--yet the only case the documentation says null is returned is if an error happened. In fact, no OpenGL error occurs at all, anywhere!

Basically, I want to know why this happens, and prevent it. Did I screw up the context creation somehow? Why wouldn't it throw an error? Is this OpenGL driver just terrible?

---

One other potentially-relevant fact: on AMD CodeXL, I get the following output on Windows:

Debug String: CodeXL warning: The debugged process asked for an extension function pointer (wglCreateContextAttribsARB) from one render context, but called this function pointer in another render context (context #1)

This should not be possible either; as you can see, that function is only ever called when the basic context is bound, using the pointer loaded while the basic context was bound. Additionally, at the time this message appears, only one context had been created, so . . .


Thanks,
-G

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Advertisement

Do you have glx 1.3 ? This is the minimum requirement for this in order to work. Also, I don't see any framebuffer configs. If you show your code, people could help you more easily.

Also, you might be interested in reading this.

Finally, generally nowadays, people tend to use existing libraries for doing this (ie, SDL, SFML, glfw...). These are helpful.

Why disable the context on line 5, only to turn it on again on 7? and why get two pointers to CreateContextAttribs? seems odd, or are these sanity checks?

Generally you

CreateContext(old)

MakeCurrent(old)

load CreateContextAttribs // get ptr

call CreateContextAttribs // get the new context

MakeCurrent(null) // done with old

DeleteContext(old) // delete old

MakeCurrent(new)

// off you go

@_Silence_: GLX version on this system is 1.4. The FB configs load is pretty standard, using glXChooseFBConfig, and the result is queried for validity. The code is open-source, albeit the latest version is not online. If you (or someone else) would like to see it, I can update the repo; the reason I didn't lead with that is that the code is quite lengthy; much control and additional functionality needs to be exposed. This is also the reason I moved from using existing context/windowing libraries (I've worked extensively with wx, Qt, SDL, and GLUT previously, and am somewhat familiar with GLFW).

@NumberXaero: Basically what's happening is there is a "Context" object which sets the context at the beginning of its constructor, and unsets it at the end. This, along with some other logic in there, ensures that the bound context is the same before/after making the "Context" object. The constructors are (lines 1-5) and (lines 7-13). Each context loads its own pointers automatically, which is why the second context gets its own pointer, even though it didn't have to.

I thought it best to present the problem as simply as possible, with just the raw API commands. Perhaps more commands would be helpful? Or perhaps someone wants to dig through the source (it's actually very readable; just long)? Suggestions?

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Basically, does a copy/paste from the example given in the link I gave previously work ?

Plus, you didn't tell what you put in your glGetString. For example, GL_EXTENSIONS will return null on OpenGL 3.2 and above (and this is normal) whereas it was returning a full list of extensions prior to this version.

Did you check for errors using glGetError?
https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glGetError.xml

This topic is closed to new replies.

Advertisement