OpenGL framebuffer rendering stopped working when I switched to GLEW. Am I using it wrong?
EDIT: Solved. Silly mistakes. :)
My project uses the old immediate mode OpenGL since I've been spending quite a bit of time just trying to figure out how to cleanly transition it to modern OpenGL. The first step I've determined is to pull in GLEW for finding extensions, as an alternative to using SDL_GL_GetProcAddress (like so) to find them (which would be considerably more manual effort).
Unfortunately, when I made the switch from using SDL_GL_GetProcAddress to using GLEW, my framebuffer objects started rendering in a messed up way. I currently use framebuffers to transition between scenes or game states (e.g. blends, fades, or distortions). When a transition begins, all the effects work correctly, but the rendering of the previous scene looks really broken.
The code change to use GLEW is here. I'm not sure what's going wrong that would've caused this. GLEW is a pretty proven library so it's very clearly something that I'm doing wrong. But I would expect that whether I use GLEW or SDL_GL_GetProcAddress, the output ought to be the same.
Note that even if I prioritize the extension function over the ARB function, I get the exact same behavior.
I'm running this on a MacBook Pro 2011 with Yosemite installed.
Can anyone see where I went wrong here? Thanks in advance for your time!
Posted Feb 8, 2016, 1:35 AM UTC · edited
By the way, your old SDL code was wrong; just because
GetProcAddressreturns a non-null pointer does not mean that the function/extension is actually implemented. For example under Linux/X11, I could callGetProcAddress("glThisDoesntExist")and get a non-null function pointer (that I could even call).The only correct way to check if an extension is present is to parse the string returned via
glGetString(GL_EXTENSIONS)(or if you've created a core context, querying the number of extensions viaglGetIntegerv(GL_NUM_EXTENSIONS, &extCount)and iterating through them viaglGetStringi(GL_EXTENSIONS, i)).Dang! That's actually good to know. I was wondering why GLEW seemed so much heavier than I had expected; this kind of additional logic explains it. :)
So what would
GetProcAddressgive you, in the scenario you described? If you called it, would it be undefined behavior? Or does it do something predictable with that bad input?Thank you for the additional info, by the way. I no longer intend to use
GetProcAddressbut it's good to have a better understanding of its limitations.The reason GLEW "seems heavy" is because it queries and then calls
GetProcAddressif available for every extension in existence. By now, this is quite a lot. It's not really that noticeable though, maybe takes around 100ms, not sure.I believe calling a function pointer returned by
GetProcAddressfor an extension that's not present is undefined behavior; it might crash, the driver might print an error message, anything could happen. Best is to avoid UB :)Thanks for your help earlier! I have a new question about GLEW, actually. Since the result of
GetProcAddressisn't guaranteed to returnnullptrif an extension is unavailable, what would a run-time extension check look like? The usage of GLEW mainly involves using macros AFAIK, so that means that I can check what's available on my platform, but that isn't useful for checking what's available on a destination platform. For example, if I checkGL_VERSION_1_5, that's going to be turned to1by my preprocessor, and so all of my sub-1.5 code will get pruned by any decent optmizer.Do I need to use
glGetStringin conjunction with GLEW to figure out what extensions are available at run-time, or does GLEW expose an easier way that I'm not aware of?Don't use the
GL_macros in your code, they're solely guard macros to prevent duplicate typedefs/defines.What you want are the
GLEW_macros, eg. to check at runtime whether your context is at least version 1.5, you'd branch onGLEW_VERSION_1_5. Analogous, checking whetherARB_framebuffer_objectis available is done viaGLEW_ARB_framebuffer_object.