3

I am trying to set up an OpenGL window with an alpha channel in its color buffer. Unfortunately, my current setup is creating a GL_RGB back and front buffer (as reported by gDEBugger, and as shown by my experiments).

I set up the window like so:

PIXELFORMATDESCRIPTOR pfd;
ZeroMemory(&pfd,sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24; //note by docs that alpha doesn't go here (though putting 32 changes nothing)
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;

I have also tried more specifically:

PIXELFORMATDESCRIPTOR pfd = {
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,
    24,
    8,0, 8,8, 8,16, 8,24, //A guess for lil endian; usually these are 0 (making them 0 doesn't help)
    0, 0,0,0,0,
    24, //depth
    8,  //stencil
    0,  //aux
    PFD_MAIN_PLANE,
    0,
    0, 0, 0
};

My understanding is that when I call ChoosePixelFormat later, it's returning a format without an alpha channel (though why, I don't know).

I should clarify that when I say alpha buffer, I mean just a simple alpha buffer for rendering purposes (each color has an alpha value that fragments can be tested against, and so on). I do NOT mean a semi-transparent window or some other effect. [EDIT: So no, I am not at this time interested in making the window itself transparent. I just want an alpha channel for the default framebuffer.]

[EDIT: This is part of a cross-platform windowing backend I'm writing. My code is always portable. I am not using a library that provides this functionality since I need more control.]

geometrian
  • 14,775
  • 10
  • 56
  • 132
  • 1
    You shouldn't ever use `windows.h` when using OpenGL programming. That defeats the whole cross-platform purpose of OpenGL! Use something like GLFW instead. – antonijn Feb 14 '13 at 12:33
  • 5
    @Antonijn not related to question – Bartek Banachewicz Feb 14 '13 at 12:34
  • @BartekBanachewicz I know, that's why it's a comment and not an answer. – antonijn Feb 14 '13 at 12:34
  • Although I agree with you that proper window handling libraries are already there. – Bartek Banachewicz Feb 14 '13 at 12:35
  • @Antonijn: Try compiling OpenGL programs without windows.h and be in for a surprise. You need some of the preprocessor definitions found in windows.h for the GL/opengl.h include to work. Just surround the include with test if compiling for windows and you're fine. – datenwolf Feb 14 '13 at 13:07
  • possible duplicate of [How to make an OpenGL rendering context with transparent background?](http://stackoverflow.com/questions/4052940/how-to-make-an-opengl-rendering-context-with-transparent-background) – datenwolf Feb 14 '13 at 13:09
  • @datenwolf You don't. On linux and max os x you don't have to include `windows.h`. Also, GLFW will take care of that for you, so you don't actually have to worry about it. – antonijn Feb 14 '13 at 13:15
  • @Antonijn: GLFW is not a standard library and OP is creating the context with the bare Win32 API, so his program isn't portable anyway. And yes you do. Or you go the length and redefine the macros yourself. Also the OpenGL headers are not located at the same place for all platforms. MacOS X for example has them at "OpenGL/gl.h" instead of "GL/gl.h". – datenwolf Feb 14 '13 at 15:22
  • @datenwolf How is `windows.h` a standard library? – antonijn Feb 14 '13 at 15:24
  • @Antonijn: The canonical way to include OpenGL headers in portable programs is (`[LF]` denotes a newline): `#ifdef _WIN32 [LF] #define WIN32_LEAN_AND_MEAN [LF] #include [LF] #include [LF] #elif defined(__APPLE__) [LF] #include [LF] #elif defined(__unix__) [LF] #include [LF] #endif` – datenwolf Feb 14 '13 at 15:25
  • @Antonijn: windows.h it not a standard library, heck it's not even a library at all. It's a *header*, and you can safely have it in portable code, as long as you make sure it doesn't get processed in environments where it isn't available. See my other comment about the canonical, portable OpenGL include stanza. – datenwolf Feb 14 '13 at 15:26
  • @Antonijn: As long as your portable code doesn't *actively* use functions available in only one plattform having the headers in conditional processing blocks is fine. And usually those header, especially if they are plattform dependant, will introduce preprocessor macros that silently modify parts of your (portable) code to match the plattform requirements. Especially OpenGL is one of those things subject to this. Windows requires a special calling convention being applied and that is made available through a macro in windows.h – datenwolf Feb 14 '13 at 15:29
  • @datenwolf Missing the point quite a bit. The only thing I suggested was to use a different library for window management, so you don't have to worry about including different headers for different platforms. I might have worded it a bit extreme, but that was what I was getting at. This will be my last word in this, since I don't think this conversation is going to lead either of us, or the op, anywhere. – antonijn Feb 14 '13 at 15:29
  • @Antonijn: To summarize: GLFW is not part of the core OpenGL ecosystem, it's a third party library, providing a minimalistic framework. OP is using the Win32 API directly, because he wants to implement something special, not offerd by the usual frameworks, so it's plattform dependent anyway. AND last but not least: Cross plattform does not mean, that your code is plattform agnosting, but that it takes the proper measuers to be compile and linkable on all the plattforms on which the libraries and functions the code uses are available. Doing this per preprocessor macros is just fine. – datenwolf Feb 14 '13 at 15:32
  • @Antonijn: What the OP wants to do, is not offered by GLFW, so GLFW is of no help to him. – datenwolf Feb 14 '13 at 15:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24524/discussion-between-antonijn-and-datenwolf) – antonijn Feb 14 '13 at 15:34
  • @Antonijn and others: this code is part of a cross-platform windowing backend I'm writing. Every piece of production code I write is cross-platform through conditional compilation. I would be embarrassed to do otherwise. – geometrian Feb 14 '13 at 17:22
  • @IanMallett I'll forgive you then ;) – antonijn Feb 14 '13 at 17:39

1 Answers1

2

There are two key points to consider here:

  • You can do this with the default framebuffer. However, you need to request it properly. Windows's default selection mechanism doesn't seem to weight having RGBA very highly. The best course seems to be to enumerate all possible pixelmodes and then select the one you want "manually" as it were. By doing this, I was also able to specify that I wanted a 24 bit depth buffer, an accumulation buffer, and an 8-bit stencil buffer.

  • The OpenGL context must be fully valid for alpha blending, depth testing, and any even remotely advanced techniques to work. Curiously, I was able to get rendered triangles without having a fully valid OpenGL context, leading to my confusion! Maybe it was being emulated in software? I figured it out when glewInit (not to mention making a few VBOs) failed miserably. The key point is that the OpenGL context must be valid. In my case, I wasn't setting it up properly.

This problem was in the context of my currently writing a lightweight cross-platform windowing toolkit. Currently, it supports Windows through the Win32 API, Linux through X11, and I just started porting to Mac OS through X11.

At the request of some in the comments, I hereby present my humble effort thereof that others may benefit. Mac support doesn't work yet, menus aren't implemented on Linux, and user input on Linux is only half-there. As of 1/18/2013, it may temporarily be found here (people of the future, I may have put new versions on my website (look for "Portcullis")).

geometrian
  • 14,775
  • 10
  • 56
  • 132