r/opengl•
Error_Value

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

67
ancientGouda•

By the way, your old SDL code was wrong; just because GetProcAddress returns a non-null pointer does not mean that the function/extension is actually implemented. For example under Linux/X11, I could call GetProcAddress("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 via glGetIntegerv(GL_NUM_EXTENSIONS, &extCount) and iterating through them via glGetStringi(GL_EXTENSIONS, i)).

4
Error_ValueOP•

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 GetProcAddress give 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 GetProcAddress but it's good to have a better understanding of its limitations.

1
ancientGouda•

The reason GLEW "seems heavy" is because it queries and then calls GetProcAddress if 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 GetProcAddress for 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 :)

1
Error_ValueOP•

Thanks for your help earlier! I have a new question about GLEW, actually. Since the result of GetProcAddress isn't guaranteed to return nullptr if 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 check GL_VERSION_1_5, that's going to be turned to 1 by my preprocessor, and so all of my sub-1.5 code will get pruned by any decent optmizer.

Do I need to use glGetString in 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?

1
ancientGouda•

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 on GLEW_VERSION_1_5. Analogous, checking whether ARB_framebuffer_object is available is done via GLEW_ARB_framebuffer_object.

1
Error_ValueOP•

Oof, I think I found the problem. I'm binding the texture, then immediately unbinding it without drawing to it. What I'm seeing is basically an uninitialized frame buffer. :(

1