SetPixelFormat is not creating an alpha channel for OpenGL

Posted by i_photon on Stack Overflow See other posts from Stack Overflow or by i_photon
Published on 2011-11-10T02:57:31Z Indexed on 2011/11/14 9:50 UTC
Read the original article Hit count: 246

Filed under:
|
|

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);
}

© Stack Overflow or respective owner

Related posts about c++

Related posts about Windows