[OpenGL] Strange wglGetProcAddress Results..

Strange things happening to me today…

I have a GForce GTX Titan which support WGL_ARB_extension_string, WGL_ARB_pixel_format and WGL_ARB_create_context_profile.

I need to retrieve 4 functions from those extensions:
(WGL_ARB_extensions_string):
wglGetExtensionsStringARB
(WGL_ARB_pixel_format):
wglChoosePixelFormatARB
wglGetPixelFormatAttribivARB
(WGL_ARB_create_context_profile):
wglCreateContextAttribsARB

What’s strange is that using wglGetProcAddress to retrieve those functions, I get Null pointer for 2 of them:
wglGetPixelFormatAttribivARB
and
wglCreateContextAttribsARB

Both functions are normally supported. and I get a valid pointer for wglChoosePixelFormatARB but a Null pointer for wglGetPixelFormatAttribivARB while both are part of the same extension supported by the GTX Titan card.

Anyone experienced something similar ?
Perhaps an issue with the NVidia drivers and 32-bit application ?
(as a side note I get correct pointers with another dev environment in 64-bit).

Perhaps tomorrow it will work ? :wink:
Anyway, strange day.

Cheers,
Guy.

Even more strange…

When I change the call order of my wglGetProcAddress I get different results, some functions get valid pointer some other Null pointer.
(now I get valid pointer for wglGetPixelFormatAttribivARB but Null pointer for wglGetExtensionsStringARB !)

The order itself seems unpredictable.

Twilight Zone today :wink:

Cheers,
Guy.

I’ve some experience with OpenGL drivers not working in strange situations.
Some ideas:

  • WGL cares about the context - if you haven’t created a valid window that is visible, it may not work.
  • there are Windows OpenGL drivers which are just buggy. What driver version?
  • there are OpenGL cards which are just buggy - the GMA 9xx series seems to be particularly bad.

Thanks for your suggestions Michael. Indeed I’m not sure where to go, I’m a bit stuck here.

Regarding the OpenGL Context I’ve checked it, I have a very valid context at each wglGetProcAddress call.
Regarding the drivers I’m using version 9.18.13.1393, I’ll try to update to see if I get any difference.
Regarding the card itself, it’s a Titan, I never had a problem with it so far.

But what makes me think more and more that it is a Xojo related issue more than a card or a driver issue is that when I change the call order of my wglGetProcAddress, I get different results.

Plus, I have a similar code that I am testing in PureBasic at the moment, both in 32-bit and in 64-bit, and I get correct results, valid pointers each time for each 4 functions.

But in Xojo I’m not sure where to look at/for now. I’ve tried to suspend background tasks, or on the contrary I’ve tried calls to App.DoEvents and even App.YieldToNextThread in between each wglGetProcAddress call but without success. I’ve even tried with a loop at each call until I get a valid result… no success. I still get 2 Null pointers over 4 calls (whatever the order so it’s not always from the same 2 functions I get Null pointers.).

Very strange.

Cheers,
Guy.

My guess is this: Xojo changed their threading model in the 2013 versions. As a result, OpenGL (WGL) calls which used to work without setting the context will now fail. Make sure that you are using wglMakeCurrent() properly in each method.

That’s interesting.

If I use a wglMakeCurrent call before each wglGetProcAddress, it works but only if I call wglGetProcAddress for wglGetPixelFormatAttribivARB first. If not, I still get a Null pointer for this function.

Well, at least I’m now getting all my wgl valid pointers consistently.

I’m a bit scary by the workaround though, I’m not sure what will happen when I’ll use wglGetProcAddress on the OpenGL extensions…

Thanks a lot for your suggestion, I can now move on to the next problem :slight_smile:

Cheers,
Guy.

Hmm… after some more experimentation, it seems the Context is not really the key point to make this work.

Since I’ve moved the call to retrieve the “wglGetPixelFormatAttribivARB” function pointer into first position, even when not calling wglMakeCurrent, it works consistently. I get all my valid pointers.

Interestingly, “wglGetPixelFormatAttribivARB” is the longest function name with 28 characters. I wonder if the issue wouldn’t be related to some internal string buffer not expanding correctly after a first call (having then truncated names which of course would not be found by the driver)…

Cheers,
Guy.

From memory: if you’re using the OpenGLSurface outside of the Render event and dealing with threads, you’ll need to be a bit careful. Before you start manipulating things, call your OpenGLSurface’s MakeCurrent method and when you’re done, detach the context with wglMakeCurrent (passing in 0 for both parameters).

After further experimentations it seems my issue is definitely not related to the OpenGL context.

I’m usually pretty comfortable setting things up properly with OpenGL - and indeed with my tests with PureBasic I have no issue at all - and I’ve double checked how I attach and detach contexts.

The simple fact my calls (4 wglGetProcAddress in a row) consistently success with a certain order and always fail with another order of execution leads me to think it is related to the length of the queried function names.

In short, calling for the shortest one first and the longest one last always fail. Reversing the order always success.

I’ll try to create a simple test application with repro-steps for this to see if it is indeed a Xojo issue or if I’m doing something really stupid I don’t see.

Cheers,
Guy.

Ok, I found the issue…

It was, indeed, related to strings, but I was doing something stupid…

My function was declared as such:

Protected Function GetProcAddress(lpszProc as MemoryBlock) As Ptr //PROC wglGetProcAddress(LPCSTR plszProc); Soft Declare Function CallGL Lib kWGLLIB Alias "wglGetProcAddress" ( lpszProc as Ptr ) as Ptr Return CallGL(lpszProc) End Function
Now I’m using the correct way:

Protected Function GetProcAddress(lpszProc as String) As Ptr //PROC wglGetProcAddress(LPCSTR plszProc); Soft Declare Function CallGL Lib kWGLLIB Alias "wglGetProcAddress" ( lpszProc as CString ) as Ptr Return CallGL(lpszProc) End Function
My bad and sorry for the noise…

Cheers,
Guy.

Thanks for sharing the solution Guy.

Definitely good to know to prevent the same issue in my own projects.

You’re welcome Alwyn.

Always glad to help (even by being stupid :wink: ).

Cheers,
Guy.