Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Is there a way to get Alpha on DIB?

Hybrid View

  1. #1
    Newbie Newbie
    Join Date
    Aug 2012
    Posts
    2

    Is there a way to get Alpha on DIB?

    I am exploring the possibility to render a main windows dialog using OpenGL which could have 32-bit per pixel (8-bit alpha, 24-bit color).

    So, far I get the render to work and display to work, but the alpha byte stay 0x00. The alpha is working in OpenGL and as well on my main window, as I could get some alpha effect when I process this byte in software. However, this slow down the render and I cannot retrieve what was the exact alpha-value from the OpenGL buffer.

    The result currently look like that:




    But as you can see, the triangles render in OpenGL is not in transparent but most likely mix in a more like a add-value... where on the black it look nice, on the white, you don't see the triangle but all white.

    Looking to the alpha byte they are all zeroes. If I replace the alpha when 0, to a value related with R,G,B... I get a result that show that the win32 stuff is working.




    This code work in windows XP up to windows 8. For a windows size of 800x600 pixels, I get a FPS that is currently not as good as I would like... even for this simple example on a good PC.

    I think it would be very interesting if I can first get the alpha byte set in the DIB... then to check how I can improve the FPS for slow end machine.

    I have start to look at DirectX stuff, to see what could be done. The code below show nothing using DirectX... as I am looking how to get the render be into buffer which would be render on a windows. I am looking just to see what will be the performance. But, I would prefer OpenGL as it may work on Linux as well.



    Here is my code below... type of project win32 c++ in MSVC 2010.

    So, if someone has an idea how to modify it to get the alpha byte being copy... let me know!

    Code :
    #define _WIN32_WINNT 0x0500
     
    #include <windows.h>
    #include "stdafx.h"
    //#include <windowsx.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    //#include <GL/glaux.h>
    #include <mmsystem.h>
    #include <stdio.h>
     
    #pragma comment (lib, "opengl32.lib")
    #pragma comment (lib, "glu32.lib")
    #pragma comment (lib, "winmm.lib")
    //#pragma comment (lib, "glaux.lib")
    #include <d3d9.h>
     
    // include the Direct3D Library file
    #pragma comment (lib, "d3d9.lib")
     
    // global declarations
    LPDIRECT3D9 d3d = NULL;    // the pointer to our Direct3D interface
    LPDIRECT3DDEVICE9 d3ddev = NULL;    // the pointer to the device class
     
    #include <assert.h>
    #include <tchar.h>
    #include <math.h>
    #define PI 3.14159265359
     
    #ifdef  assert
    #define verify(expr) if(!expr) assert(0)
    #else verify(expr) expr
    #endif
     
    const TCHAR szAppName[]=_T("TransparentGL");
    const TCHAR wcWndName[]=_T("WS_EX_LAYERED OpenGL");
     
    HDC hDC;            
    HGLRC m_hrc; 
    HWND g_hWnd;
    int w(800);
    int h(600); 
    bool g_bSwitchAlpha = false;//false;
    bool g_bTryFaster = false;//true;
     
    HDC pdcDIB;                 
    HBITMAP hbmpDIB;            
    void *bmp_cnt(NULL);        
    int cxDIB(0); 
    int cyDIB(0);   
    BITMAPINFOHEADER BIH;    
    BITMAPV5HEADER BIHA;
     
    //#define USE_DIRECT_X
     
    BOOL initSC()
    {
        glEnable(GL_ALPHA_TEST);        
        glEnable(GL_DEPTH_TEST);        
        glEnable(GL_COLOR_MATERIAL);
     
        glEnable(GL_LIGHTING);          
        glEnable(GL_LIGHT0);            
     
        glEnable(GL_BLEND);             
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    	glClearColor(0, 0, 0, 0);
    	return 0;
    }
     
    void resizeSC(int width,int height)
    {
        glViewport(0,0,width,height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
     
        glMatrixMode(GL_MODELVIEW );
        glLoadIdentity();
    }
     
    BOOL renderSC()
    {   
    	DWORD	dwTime, dwTime2;
    	static float t = 0.0f;
    	float a1, a2, a3, x,y;
    	int i, j;
     
    	t=timeGetTime()/1.4f + 350.0f * sin(2.0f * PI * timeGetTime()/1.4f* 1.0f /1000);
    #ifndef USE_DIRECT_X
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glPushMatrix();
        glColor3f(0, 1, 1);
        glBegin(GL_TRIANGLES);                              // Drawing Using Triangles
    #else
    	// clear the window to a deep blue
        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
     
        d3ddev->BeginScene();    // begins the 3D scene
     
        // do 3D rendering on the back buffer here
     
    #endif
     
    	a3 = 0.0f;
    	for(j=0;j<5;++j)
    	{
    		x = 0.3f * sin(2.0f * PI * t* 0.25f /1000);
    		y = 0.3f * sin(2.0f * PI * t* 0.5f /1000);
    		for(i=0;i<3;++i)
    		{
    			a1 = 0.75f * cos(2.0f * PI * t *0.3f / 1000 + 2.0f * PI * i /3);
    			a2 = 0.75f * sin(2.0f * PI * t *0.3f  / 1000 + 2.0f * PI * i /3);
    #ifndef USE_DIRECT_X
    			if (i==0)
    				glColor4f(0.8f,0.0f,0.0f,1.0f);                      // Set The Color To Red
    			else if (i==1)
    				glColor4f(1.0f,1.0f,0.0f,1.0f);                      // Set The Color To Green
    			else
    				glColor4f(0.0f,0.0f+j*0.1f,2.0f,0.0f);                      // Set The Color To Blue
    			glVertex3f( a1+x, a2+y, a3);                  // Top
    #else
    #endif
    		}
    		t += (38.0f+30.0f*sin(2.0f*PI*t*0.70f/1000))*(j+1+j*0.1f);
    		a3-=0.01f;
    //		a3+=1.5f;
    	}
    #ifndef USE_DIRECT_X
        glEnd();
     
        glPopMatrix();
        glFlush();
    #else
        d3ddev->EndScene();    // ends the 3D scene
        d3ddev->Present(NULL, NULL, NULL, NULL);    // displays the created frame
    #endif
    /*        glColor4f(0.0f,1.0f,0.0f,0.0f);                      // Set The Color To Green
            glVertex3f(-1.0f,-0.0f-a, 0.0f);                  // Bottom Left
            glColor4f(0.0f,0.0f,1.0f,1.0f);                      // Set The Color To Blue
            glVertex3f( 1.0f,0.0f-a, 0.0f);                  // Bottom Right*/
     
        return 0;
    }
     
    // DIB -> hDC
    void draw(HDC pdcDest)
    {
    	POINT pptDst, pptSrc;
    	SIZE pSize;
    	int i,j;
    	DWORD dwValue;
    	DWORD dwTime = timeGetTime();
        assert(pdcDIB);
    	BLENDFUNCTION blendfunc;
     
    	blendfunc.AlphaFormat = AC_SRC_ALPHA;
    	blendfunc.BlendFlags = 0;
    	blendfunc.SourceConstantAlpha = 255;
    	blendfunc.BlendOp = AC_SRC_OVER;
     
    //	AlphaBlend(pdcDest,  0, 0, w, h, pdcDIB, 0, 0, w, h, blendfunc);
    //	TransparentBlt(pdcDest, 0, 0, w, h, pdcDIB, 0, 0, w, h, 0);
    //    verify(BitBlt(pdcDest, 0, 0, w, h, pdcDIB, 0, 0, SRCCOPY));
    	pptDst.x = 40;
    	pptDst.y = 30;
    	pptSrc.x = 0;
    	pptSrc.y = 0;
    	pSize.cx = w;
    	pSize.cy = h;
     
    	BOOL bRet;
     
    	unsigned char *pBuf;
    /*	pBuf = new unsigned char[4*w*h];
    	BITMAPINFO	bmi;
    	memset(&bmi, 0, sizeof(BITMAPINFO));
    	bmi.bmiHeader.biBitCount = 32;
    	bmi.bmiHeader.biHeight = h;
    	bmi.bmiHeader.biWidth = w;
    	bmi.bmiHeader.biCompression = BI_BITFIELDS;
    	bmi.bmiHeader.biSize = sizeof(BITMAPINFO);*/
    	HBITMAP hbm;
    //	hbm = CreateCompatibleBitmap(pdcDIB, w, h);
     
    	DWORD *pBmp = (DWORD *) bmp_cnt;
    //	DWORD dwValue;
    	int a, b;
    	if (g_bSwitchAlpha)
    	{
    	for(i=0;i<w*h;++i)
    	{
    		if ((pBmp[i]&0xFF000000)==0)
    		{
    		a = (pBmp[i]&0x00FF00)>>8;
    		a+= pBmp[i]&0x00FF;
    		a+= (pBmp[i]&0xFF0000)>>16;
    		a*=1.0f+0.5f * sin(2.0f * PI * timeGetTime()*0.2f/1000);
    		if (a>0xFF) a = 0xFF;
     
    		pBmp[i]|= (a<<24);
    		}
    	}
    	}
     
    //	int nres;
    //	nres = GetDIBits(pdcDIB, hbm, 0, h, pBuf, &bmi, DIB_RGB_COLORS);
     
    //	if ((timeGetTime()%1000)<500)
    	if (g_bTryFaster)
    		bRet = UpdateLayeredWindow(g_hWnd, pdcDest, &pptDst, &pSize, pdcDIB, &pptSrc, RGB(0,0,0), &blendfunc, ULW_COLORKEY);
    	else
    		bRet = UpdateLayeredWindow(g_hWnd, pdcDest, &pptDst, &pSize, pdcDIB, &pptSrc, RGB(0,0,0), &blendfunc, ULW_ALPHA);
     
    	//	else
    	//	bRet = UpdateLayeredWindow(g_hWnd, pdcDest, &pptDst, &pSize, pdcDIB, &pptSrc, RGB(0,0,0), &blendfunc, ULW_ALPHA);
    /*	if (g_bTryFaster)
    		bRet = UpdateLayeredWindow(g_hWnd, pdcDest, &pptDst, &pSize, pdcDIB, &pptSrc, RGB(0,0,0), &blendfunc, ULW_OPAQUE|ULW_COLORKEY);
    	else
    		bRet = UpdateLayeredWindow(g_hWnd, pdcDest, &pptDst, &pSize, pdcDIB, &pptSrc, RGB(0,0,0), &blendfunc, ULW_ALPHA);*/
    //	else
    	//	bRet = UpdateLayeredWindow(g_hWnd, pdcDest, &pptDst, &pSize, pdcDIB, &pptSrc, RGB(0,0,0), &blendfunc, ULW_ALPHA|ULW_OPAQUE);
    //	AlphaBlend(pdcDest,  0, 0, w, h, pdcDIB, 0, 0, w, h, blendfunc);
    //	dwTime = timeGetTime() - dwTime;
    //	char szDbg[MAX_PATH];
    //	sprintf(szDbg, "draw: %d ms\n", dwTime);
    //	OutputDebugString(szDbg);
    }
     
    void CreateDIB(int cx, int cy)
    {
        assert(cx > 0); 
        assert(cy > 0);
     
        cxDIB = cx ;
        cyDIB = cy ;
     
    /*    int iSize = sizeof(BITMAPINFOHEADER);   
        memset(&BIH, 0, iSize);
     
        BIH.biSize = iSize;
        BIH.biWidth = cx;   
        BIH.biHeight = cy;  
        BIH.biPlanes = 1;   
        BIH.biBitCount = 32;    
        BIH.biCompression = BI_RGB;*/
    	int iSize = sizeof(BITMAPV5HEADER);
    	memset(&BIHA, 0, iSize);
     
        //The following mask specification specifies a supported 32 BPP
        //alpha format for Windows XP.
    	BIHA.bV5Size			= sizeof(BITMAPV5HEADER);
        BIHA.bV5Width           = cx;
        BIHA.bV5Height          = cy;
        BIHA.bV5Planes			= 1;
        BIHA.bV5BitCount		= 32;
    	BIHA.bV5SizeImage		= w*h*4;
    	BIHA.bV5CSType		= LCS_sRGB;
        BIHA.bV5Compression = BI_BITFIELDS;
        BIHA.bV5RedMask   =  0x00FF0000;
        BIHA.bV5GreenMask =  0x0000FF00;
        BIHA.bV5BlueMask  =  0x000000FF;
        BIHA.bV5AlphaMask =  0xFF000000;
        if(pdcDIB) 
            verify(DeleteDC(pdcDIB));
     
        pdcDIB = CreateCompatibleDC(NULL);
        assert(pdcDIB);
     
        if(hbmpDIB) 
            verify(DeleteObject(hbmpDIB));
     
        hbmpDIB = CreateDIBSection(
            pdcDIB,         
            (BITMAPINFO*)&BIHA,  
            DIB_RGB_COLORS,     
            &bmp_cnt,       
            NULL,
            0);
    	memset(bmp_cnt, 0x44, 4*w*h);
     
        assert(hbmpDIB);
        assert(bmp_cnt);
     
        if(hbmpDIB)
            SelectObject(pdcDIB, hbmpDIB);
    }
     
    BOOL CreateHGLRC()
    {
        DWORD dwFlags = PFD_DIRECT3D_ACCELERATED | PFD_DRAW_TO_BITMAP;
    //	dwFlags = PFD_DRAW_TO_BITMAP|PFD_GENERIC_ACCELERATED;
     
        PIXELFORMATDESCRIPTOR pfd ;
        memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)) ;
        pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 
        pfd.nVersion = 1;                       
        pfd.dwFlags =  dwFlags ;                
        pfd.iPixelType = PFD_TYPE_RGBA ;        
        pfd.cColorBits = 32 ;                   
        pfd.cDepthBits = 24 ;
    	pfd.cStencilBits = 8;
    	pfd.cAlphaBits = 8;
    	pfd.iLayerType = PFD_MAIN_PLANE;  
     
     
       int PixelFormat = ChoosePixelFormat(pdcDIB, &pfd);
       if (PixelFormat == 0){
          assert(0);
          return FALSE ;
       }
     
       BOOL bResult = SetPixelFormat(pdcDIB, PixelFormat, &pfd);
       if (bResult==FALSE){
          assert(0);
          return FALSE ;
       }
     
       m_hrc = wglCreateContext(pdcDIB);
       if (!m_hrc){
          assert(0);
          return FALSE;
       }
     
       return TRUE;
    }
     
    BOOL CreateHDXRC(HWND hWnd)
    {
    	D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information
     
    	ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use
    	d3dpp.Windowed = TRUE;    // program windowed, not fullscreen
    	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames
    	d3dpp.hDeviceWindow = hWnd;    // set the window to be used by Direct3D
     
    	// create a device class using this information and information from the d3dpp stuct
    	d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
     
     
     
    	return TRUE;
    }
     
    LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	static int s_enter = 0;
        PAINTSTRUCT ps;
    	int i;
    	char szDbg[MAX_PATH];
    	char szLastDbg[MAX_PATH];
    	DWORD	dwTime;
    	static DWORD s_dwTime = 0;
    	static int s_nTime = 0;
    	static DWORD s_cumTime = 0;
     
        switch(msg) 
        {
            case WM_ERASEBKGND:
                return 0;
            break;
     
            case WM_CREATE:
            break;
     
            case WM_DESTROY:
    #ifndef USE_DIRECT_X
                if(m_hrc)
                {
                    wglMakeCurrent(NULL, NULL);
                    wglDeleteContext(m_hrc) ;
                }
    #else
    			if (d3ddev)
    				d3ddev->Release();    // close and release the 3D device
    			if (d3d)
    			    d3d->Release();    // close and release Direct3D		
    #endif
                PostQuitMessage(0) ;
            break;
     
            case WM_PAINT:
                hDC = BeginPaint(hWnd, &ps);
                renderSC(); // OpenGL -> DIB
                draw(hDC);  // DIB -> hDC
                EndPaint(hWnd, &ps);
            break;
    		case WM_TIMER:
    			if (s_enter!=0) return FALSE;
    			if (s_dwTime==0) s_dwTime = timeGetTime();
    			++s_enter;
    			dwTime = timeGetTime();
    //#ifndef USE_DIRECT_X
    			hDC = GetDC(hWnd);
    //            hDC = BeginPaint(hWnd, &ps);
                renderSC(); // OpenGL -> DIB
                draw(hDC);  // DIB -> hDC
    			ReleaseDC(hWnd, hDC);
    //#endif
    			--s_enter;
    			dwTime = timeGetTime() - dwTime;
    			s_cumTime+=dwTime;
    			++s_nTime;
    //			OutputDebugString(szLastDbg);
    			s_dwTime = timeGetTime();
     //           EndPaint(hWnd, &ps);
    		break;
     
            case WM_SIZE:
                w = LOWORD(lParam); h = HIWORD(lParam);         
    #ifndef USE_DIRECT_X
    			// --- initialize Open GL ---
                wglMakeCurrent(NULL, NULL);
                wglDeleteContext(m_hrc);
     
                CreateDIB(w, h);
                CreateHGLRC();
                verify(wglMakeCurrent(pdcDIB, m_hrc));
     
                initSC();
                resizeSC(w, h);
                renderSC();
    #else
    			// --- initialize Direct X ---
    			d3d = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface
    			CreateDIB(w, h);
    			CreateHDXRC(hWnd);
                renderSC();
    #endif
            break;
    		case WM_KEYDOWN:
    			if (toupper(LOBYTE(wParam))=='A')
    			{
    				sprintf(szLastDbg, "Average: %d ms (cumul. time: %d ms, count: %d)\n", s_cumTime/(s_nTime), s_cumTime, s_nTime);
    				MessageBox(NULL, szLastDbg, "Debug", MB_OK);
    			}
    			else if (toupper(LOBYTE(wParam))=='Q')
    			{
    				g_bTryFaster = !g_bTryFaster;
    				s_cumTime = 0;
    				s_nTime = 0;
    			}
    			else
    			{
    				g_bSwitchAlpha = !g_bSwitchAlpha;
    				s_cumTime = 0;
    				s_nTime = 0;
    			}
    			break;
     
            default: 
                return DefWindowProc(hWnd,msg,wParam,lParam);
        }
     
        return 0;
    }
     
    int WINAPI _tWinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str,int nWinMode)
    {   
        WNDCLASSEX wc;
        memset(&wc, 0, sizeof(wc));
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = (WNDPROC)WindowFunc;
        wc.cbClsExtra  = 0;
        wc.cbWndExtra  = 0;
        wc.hInstance = hThisInst;
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH) (COLOR_WINDOW);
        wc.lpszClassName = szAppName;
     
        if(!RegisterClassEx(&wc))
        {
            MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
            return FALSE;
        }
     
        HWND hWnd = CreateWindowEx(WS_EX_LAYERED, szAppName, wcWndName,
                        WS_VISIBLE | WS_POPUP, 200, 150, w, h,
                        NULL, NULL, hThisInst, NULL);
        if(!hWnd){
            MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
            return FALSE;
        }
     
    //    verify(SetLayeredWindowAttributes(hWnd, 0x0, 255, LWA_ALPHA));
    	g_hWnd = hWnd;
        MSG msg;
    	SetTimer(hWnd, 1, 25, NULL);
        while(1) 
        {
            while (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){
                if (GetMessage(&msg, NULL, 0, 0))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                else return 0;
            }
        } 
     
        return (FALSE); 
    }
    Last edited by fcycles; 08-10-2012 at 09:12 AM. Reason: Correct the link for the attached images, so we can see them in normal size.

  2. #2
    Newbie Newbie
    Join Date
    Aug 2012
    Posts
    2
    I made some progress, on the DirectX support and got the alpha included with the RGB. The performance is 1 ms to update the window on win7 using a modern PC (however this drop to 300 ms using a Pentium III 800MHz, with Windows XP).

    That give me some hopes that there is a way in OpenGL too with some good performance. I need to found out if the very low performance on old PC can be improve by removing some of the visual features.

    here is a screen shot of my dialog box (yeah.. yeah.. those colored computed by the graphic cards triangles is a dialog box).



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •