I've been able to do this before, and I don't know what changed between two weeks ago and the last windows update, but for some reason SetPixelFormat isn't creating an alpha channel.
gDebugger shows that the window's back buffer only has 3 channels.
White+0 alpha renders as white.
So there is something inherently wrong with what I was doing, or an update broke it.
The code below should be paste-able into an empty VS project.
#include <Windows.h>
#include <dwmapi.h>
#include <gl/GL.h>
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"dwmapi.lib")
HWND hWnd = 0;
HDC hDC = 0;
HGLRC hRC = 0;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = WndProc;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = TEXT("why_class");
RegisterClassEx(&wcex);
// no errors
hWnd = CreateWindowEx(
NULL,
TEXT("why_class"),
TEXT("why_window"),
WS_OVERLAPPEDWINDOW,
128,128,
256,256,
NULL,
NULL,
hInstance,
NULL
);
// no errors
PIXELFORMATDESCRIPTOR pfd = {0};
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW|
PFD_SUPPORT_OPENGL|
PFD_DOUBLEBUFFER|
PFD_SUPPORT_COMPOSITION;
pfd.cColorBits = 32;
pfd.cAlphaBits = 8; // need an alpha channel
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
hDC = GetDC(hWnd);
int i = ChoosePixelFormat(hDC,&pfd);
SetPixelFormat(hDC,i,&pfd);
// no errors
hRC = wglCreateContext(hDC);
// no errors
wglMakeCurrent(hDC,hRC);
// no errors
// EDIT: Turn on alpha testing (which actually won't
// fix the clear color problem below)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// EDIT: Regardless of whether or not GL_BLEND is enabled,
// a clear color with an alpha of 0 should (or did at one time)
// make this window transparent
glClearColor(
0,0,0, // if this is (1,1,1), the window renders
// solid white regardless of the alpha
0 // changing the alpha here has some effect
);
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE|DWM_BB_TRANSITIONONMAXIMIZED;
bb.fEnable = TRUE;
bb.fTransitionOnMaximized = TRUE;
DwmEnableBlurBehindWindow(hWnd,&bb);
// no errors
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// no errors
MSG msg = {0};
while(true){
GetMessage(&msg,NULL,NULL,NULL);
if(msg.message == WM_QUIT){
return (int)msg.wParam;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
// this vertex should be transparent,
// as it was when I last built this test
//
// it renders as white
glColor4f(1,1,1,0);
glVertex2f(0,0);
glColor4f(0,1,1,1);
glVertex2f(1,0);
glColor4f(1,0,1,1);
glVertex2f(0,1);
glEnd();
SwapBuffers(hDC);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
}return 0;
default:
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}