TIGSource Forums

Developer => Technical => Topic started by: Lemming on July 26, 2009, 05:36:31 AM



Title: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Lemming on July 26, 2009, 05:36:31 AM
Hi!

I'm growing insane trying to get EXT_framebuffer_object to work in Windows using MinGW.

Usually I use Linux where GenRenderbuffersEXT etc. are defined by including <GL/gl.h>. The app is written portably, relying on standard libs, SDL and OpenGL, so compiling it shouldn't really be a problem, is what I thought.

Then I ran into Windows' implementation of OpenGL, which seems severely outdated and didn't include any FBO constants or functions. Now I've been sitting for hours trying to get it to work, where I run into other problems trying to copypaste others' code. PFNGLGENFRAMEBUFFERSEXTPROC for one isn't defined. It may have to do with "GL/wglext.h" not existing in the MinGW distribution, but was used with the code. Similar problems make me go insane, because this should work out of the box, instead it doesn't.

Mentioning MinGW because I suspect the library distribution with Visual Studio and MinGW is different. GL headers inside MinGW/include/GL/ are "gl.h", "glu.h" and "glext.h". The problem however seems common to Windows users, so I'm hoping that some of you've probably run into it already. But not out of spite.


tl;dr: Is there any simple way to get FBO:s running with MinGW? Preferrably without GLEW or other new dependencies.


Thankful for any help. :)


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Ivan on July 26, 2009, 08:17:07 AM
I don't know if there's a better way, but this is what I do.  HAHA

EDIT:
Hmm, on another hand, none of these define PFNGLGENFRAMEBUFFERSEXTPROC..
I'm not sure where it's defined and I'm not on windows right now to check.
Aside from the standard gl headers, im also including <CG/cgGL.h> (it's part of the CG devkit) so maybe it's in there somewhere?

Code:
#ifdef _WINDOWS

#define GL_EXT_framebuffer_object           1

#if GL_EXT_framebuffer_object
#define GL_FRAMEBUFFER_EXT                 0x8D40
#define GL_RENDERBUFFER_EXT                0x8D41
#define GL_STENCIL_INDEX1_EXT              0x8D46
#define GL_STENCIL_INDEX4_EXT              0x8D47
#define GL_STENCIL_INDEX8_EXT              0x8D48
#define GL_STENCIL_INDEX16_EXT             0x8D49
#define GL_RENDERBUFFER_WIDTH_EXT           0x8D42
#define GL_RENDERBUFFER_HEIGHT_EXT          0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
#define GL_RENDERBUFFER_RED_SIZE_EXT        0x8D50
#define GL_RENDERBUFFER_GREEN_SIZE_EXT      0x8D51
#define GL_RENDERBUFFER_BLUE_SIZE_EXT       0x8D52
#define GL_RENDERBUFFER_ALPHA_SIZE_EXT      0x8D53
#define GL_RENDERBUFFER_DEPTH_SIZE_EXT      0x8D54
#define GL_RENDERBUFFER_STENCIL_SIZE_EXT    0x8D55
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT           0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT           0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT         0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT    0x8CD4
#define GL_COLOR_ATTACHMENT0_EXT           0x8CE0
#define GL_COLOR_ATTACHMENT1_EXT           0x8CE1
#define GL_COLOR_ATTACHMENT2_EXT           0x8CE2
#define GL_COLOR_ATTACHMENT3_EXT           0x8CE3
#define GL_COLOR_ATTACHMENT4_EXT           0x8CE4
#define GL_COLOR_ATTACHMENT5_EXT           0x8CE5
#define GL_COLOR_ATTACHMENT6_EXT           0x8CE6
#define GL_COLOR_ATTACHMENT7_EXT           0x8CE7
#define GL_COLOR_ATTACHMENT8_EXT           0x8CE8
#define GL_COLOR_ATTACHMENT9_EXT           0x8CE9
#define GL_COLOR_ATTACHMENT10_EXT          0x8CEA
#define GL_COLOR_ATTACHMENT11_EXT          0x8CEB
#define GL_COLOR_ATTACHMENT12_EXT          0x8CEC
#define GL_COLOR_ATTACHMENT13_EXT          0x8CED
#define GL_COLOR_ATTACHMENT14_EXT          0x8CEE
#define GL_COLOR_ATTACHMENT15_EXT          0x8CEF
#define GL_DEPTH_ATTACHMENT_EXT            0x8D00
#define GL_STENCIL_ATTACHMENT_EXT          0x8D20
#define GL_FRAMEBUFFER_COMPLETE_EXT                        0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT           0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT   0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT           0x8CD9
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT              0x8CDA
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT          0x8CDB
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT          0x8CDC
#define GL_FRAMEBUFFER_UNSUPPORTED_EXT                     0x8CDD
#define GL_FRAMEBUFFER_BINDING_EXT         0x8CA6
#define GL_RENDERBUFFER_BINDING_EXT        0x8CA7
#define GL_MAX_COLOR_ATTACHMENTS_EXT       0x8CDF
#define GL_MAX_RENDERBUFFER_SIZE_EXT       0x84E8
#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
#endif
#endif

Code:
#ifdef _WINDOWS


PFNGLACTIVETEXTUREPROC   glActiveTexture;
PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f;
PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f;


// ARB_vertex_buffer_object
PFNGLBINDBUFFERARBPROC glBindBufferARB;
PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB;
PFNGLGENBUFFERSARBPROC glGenBuffersARB;
PFNGLISBUFFERARBPROC glIsBufferARB;
PFNGLBUFFERDATAARBPROC glBufferDataARB;
PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB;
PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB;
PFNGLMAPBUFFERARBPROC glMapBufferARB;
PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;

// GL_EXT_framebuffer_object
PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT;
PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT;
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;

#endif
   
Code:
#ifdef _WINDOWS
glActiveTexture   = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)wglGetProcAddress("glMultiTexCoord2f");
glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)wglGetProcAddress("glMultiTexCoord3f");

   // ARB_vertex_buffer_object
        glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
        glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
        glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
        glIsBufferARB = (PFNGLISBUFFERARBPROC)wglGetProcAddress("glIsBufferARB");
        glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
        glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)wglGetProcAddress("glBufferSubDataARB");
        glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)wglGetProcAddress("glGetBufferSubDataARB");
        glMapBufferARB = (PFNGLMAPBUFFERARBPROC)wglGetProcAddress("glMapBufferARB");
        glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)wglGetProcAddress("glUnmapBufferARB");
        glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)wglGetProcAddress("glGetBufferParameterivARB");
        glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)wglGetProcAddress("glGetBufferPointervARB");

        glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)wglGetProcAddress("glIsRenderbufferEXT");
        glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)wglGetProcAddress("glBindRenderbufferEXT");
        glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT");
        glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT");
        glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT");
        glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)wglGetProcAddress("glGetRenderbufferParameterivEXT");
        glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)wglGetProcAddress("glIsFramebufferEXT");
        glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
        glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT");
        glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");
        glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
        glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)wglGetProcAddress("glFramebufferTexture1DEXT");
        glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
        glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)wglGetProcAddress("glFramebufferTexture3DEXT");
        glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT");
        glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT");
        glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)wglGetProcAddress("glGenerateMipmapEXT");

#endif


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Lemming on July 26, 2009, 09:01:00 AM
I'm thinking about checking out the GLEW source and copying the bare minimum to get the FBO extension running. It's a shame that Windows doesn't provide a more up-to-date header, really.

I could also check the cgGL header out.. I'll post results once I figure out how to do this. :)


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: PsySal on July 26, 2009, 10:31:36 AM
I'd say don't try to manage GL extensions yourself. I've gone down that road and it's a sad, sorry place to be. Instead, may I suggest GLEW, the GL Extensions Wrangler:

http://glew.sourceforge.net/

I haven't used it, but I plan on it, for the next time I need an GL extensions.


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Saint on July 26, 2009, 11:00:44 AM
I manage GL extensions myself like above for a couple of reasons, mainly due to driver issues and to avoid dependencies. You mentioned that this is important to you as well so this might be superfluous, but if GLEW seems to bulky you might want to look at GL Easy Extensions (GLee);
http://www.opengl.org/sdk/libs/GLee/


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: David Pittman on July 26, 2009, 11:26:46 AM
You may just need a more recent glext.h than what MinGW ships with. Khronos defines a standard one, and I think some hardware vendors provide their own (I know NVIDIA does for sure, anyway).

http://www.opengl.org/registry/api/glext.h (http://www.opengl.org/registry/api/glext.h)
http://www.opengl.org/registry/api/glxext.h (http://www.opengl.org/registry/api/glxext.h)
http://www.opengl.org/registry/api/wglext.h (http://www.opengl.org/registry/api/wglext.h)

I checked and PFNGLGENFRAMEBUFFERSEXTPROC is defined in there, so hopefully you'd just have to do the usual address-getting boilerplate code and it would work. I don't know, I haven't touched GL in a while.


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Lemming on July 26, 2009, 11:47:23 AM
I manage GL extensions myself like above for a couple of reasons

A problem I had with doing that is that I seem to be unable to find PFNGLGENFRAMEBUFFERSEXTPROC. Do you use the method described above?

Do you know if your code compiles with MinGW, and also, what headers do you include?

wglGetProcAddress seems to be defined in wingdi.h, (WinGDI) but not the function pointer types for it. I can't seem to search google/msdn for where these are defined either. So I have to look through the headers, I think.

You may just need a more recent glext.h than what MinGW ships with. Khronos defines a standard one, and I think some hardware vendors provide their own (I know NVIDIA does for sure, anyway).

http://www.opengl.org/registry/api/glext.h (http://www.opengl.org/registry/api/glext.h)
http://www.opengl.org/registry/api/glxext.h (http://www.opengl.org/registry/api/glxext.h)
http://www.opengl.org/registry/api/wglext.h (http://www.opengl.org/registry/api/wglext.h)

I checked and PFNGLGENFRAMEBUFFERSEXTPROC is defined in there, so hopefully you'd just have to do the usual address-getting boilerplate code and it would work. I don't know, I haven't touched GL in a while.

But of course, I did actually try replacing the glext header before, which got me linking errors. Obviously, as I need to implement these function pointers. :facepalm:

This was before I got into pasting the other code that seemed to work for everyone else, though. Before stuff became clearer.

This is the tree I'll be barking up, probably making a small header/function for windows etc.


Thank you all for all the tips and pointers, I'll procrastinate and probably implement it later this week. ::)


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Saint on July 27, 2009, 12:07:10 AM
A problem I had with doing that is that I seem to be unable to find PFNGLGENFRAMEBUFFERSEXTPROC. Do you use the method described above?

Do you know if your code compiles with MinGW, and also, what headers do you include?

Yes, it compiles but I do not use glext.h either, I just typedef the function pointers myself. All of the information about the function prototypes can be found in the extension registry ( http://www.opengl.org/registry/ ).

Code:
typedef void(APIENTRY *PFNGLGENFRAMEBUFFERSPROC)(GLsizei _nFrameBuffers, GLuint *_pFrameBuffers);

Framebuffers have moved from being an EXT extension into being an ARB extension and then included in the standard, which means the older ones might have been deprecated and removed, so check for types where you exchange the EXT for ARB or remove it altogether. Careful though, I remember a few standardized functions working differently than their ARB counterparts on NVidia hardware a few months back, but that should be resolved by now.


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Lemming on July 27, 2009, 01:08:09 AM
Framebuffers have moved from being an EXT extension into being an ARB extension and then included in the standard, which means the older ones might have been deprecated and removed

Ok, I believe in following standards. Thanks for pointing out the ARB vs. EXT difference. :)


Title: Re: Using GL_FRAMEBUFFER_EXT with MinGW
Post by: Saint on July 27, 2009, 01:25:05 AM
Ok, I believe in following standards. Thanks for pointing out the ARB vs. EXT difference. :)

You are quite welcome.

Another word of warning, though, using the latest & greatest will in this case mean that people with drivers more than ~6 months old might not be able to run the game. Sure, updating drivers is usually simple enough but as a precaution I would recommend seeing if "glGenBuffers" can be found and if not try and find "glGenBuffersARB" (and possibly "glGenBuffersEXT" after that).