Thread: Rendering 32-bit images - alpha is ignored

  1. #31
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    Looking at the BITMAPINFO structure, I see the info header thing and bmiColors. The "bmiColors" thing is confusing me. What do I put in there, if anything? The documentation says it should be either RGBQuad or something involving a palette. I don't use palettes (32-bit color, no palettes with that, just raw 0 to 255 values). Seeing the description of RGBQuad, it seems as if it would turn all pixels the same color. If I put 255 in for everything except the reserved one, wouldn't that make the image all white or would it retain the original brightness (where, if I used 85, it'd be a third as bright instead)? This is what's confusing me at the moment. I've set up the HBITMAP and a third DC. I've adjusted the AlphaBlend function to using this third DC (HDCBack being the first specified (the destination), and HDCBitmap for the second specified (the source).

  2. #32
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    Well, if you want to know, DIB_RGB_COLORS indicates that no palette is used so the palette in BITMAPINFO is ignored.
    Last edited by pronecracker; 04-17-2007 at 12:20 PM. Reason: not very friendly, stupid:P

  3. #33
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    Okay, I've tested it and stuff and AlphaBlend is failing (nothing draws this time with AlphaBlend). From GetLastError, I see that there's an invalid parameter somewhere, the likely cause to it failing. Oh boy, here we go again:

    Code:
    BLENDFUNCTION AlphaUsage;
    HDC HDCBitmap; // DC for bitmaps
    
    unsigned char MountainsData[524288]; // The mountains background
    LPVOID MountainsDataPointer;
    BITMAPINFO MountainsMainInfo;
    BITMAPINFOHEADER MountainsInfo;
    LPBITMAPINFOHEADER MountainsInfoPointer;
    HBITMAP MountainsBMPHandle;
    struct SceneryData Mountains;
    
    void InitializeDrawing()
    {
    	HDCScreen = GetDC(hwnd); // set the screen buffer DC
    	HDCBack = CreateCompatibleDC(HDCScreen); // create a compatible DC, of which is to be used for drawing into the back buffer
    	HDCBitmap = CreateCompatibleDC(HDCScreen); // for AlphaBlend
    	MountainsMainInfo.bmiHeader = MountainsInfo;
    	MountainsBMPHandle = CreateDIBitmap(HDCScreen, &MountainsMainInfo.bmiHeader, CBM_INIT, MountainsData, &MountainsMainInfo, DIB_RGB_COLORS);
    	SelectObject(HDCBitmap, MountainsBMPHandle); // select the created bitmap
    	HBMPBack = CreateCompatibleBitmap(HDCScreen, 800, 600); // create compatible bitmap, used for drawing into, but not on screen
    	SelectObject(HDCBack, HBMPBack); // select the created bitmap
    	ImageHandle = DrawDibOpen(); // set the DrawDib DC handle
    	AlphaUsage.BlendOp = AC_SRC_OVER;
    	AlphaUsage.BlendFlags = 0;
    	AlphaUsage.SourceConstantAlpha = 255;
    	AlphaUsage.AlphaFormat = AC_SRC_ALPHA;
    
    ... // front and back buffer things
    
    	if (DebugTest[0] == 0)
    	{
    		DebugTest[0] = 1; // so this test is processed only once
    		DebugTest[1] = HDCBitmap; // nonzero
    		DebugTest[2] = MountainsBMPHandle; // nonzero
    		
    		sprintf(DebugDetails, "The resulting values are:\n%d\n%d\n%d\n%d\n%d.", DebugTest[1], DebugTest[2], DebugTest[3], DebugTest[4], DebugTest[5]); // for debugging
    		MessageBox(hwnd, DebugDetails, "Debug Results", MB_OK);
    	}
    }
    
    void DrawScenery()
    {
    	DrawDibDraw(ImageHandle, HDCBack, 0, 0, SkyBGInfo.biWidth, SkyBGInfo.biHeight, SkyBGInfoPointer, SkyBGDataPointer, 0, 0, SkyBGInfo.biWidth, SkyBGInfo.biHeight, 0);
    	DrawDibDraw(ImageHandle, HDCBack, 0, 240, FogInfo.biWidth, FogInfo.biHeight, FogInfoPointer, FogDataPointer, 0, 0, FogInfo.biWidth, FogInfo.biHeight, 0);
    	// DrawDibDraw(ImageHandle, HDCBack, Mountains.XMain, Mountains.YMain, MountainsInfo.biWidth, MountainsInfo.biHeight, MountainsInfoPointer, MountainsDataPointer, 0, 0, MountainsInfo.biWidth, MountainsInfo.biHeight, 0);
    	// BitBlt(HDCBack, Mountains.XMain, Mountains.YMain, MountainsInfo.biWidth, MountainsInfo.biHeight, HDCScreen, MountainsInfo.biWidth, MountainsInfo.biHeight, SRCCOPY);
    	// AlphaBlend(HDCBack, Mountains.XMain, Mountains.YMain, MountainsInfo.biWidth, MountainsInfo.biHeight, HDCScreen, 0, 0, MountainsInfo.biWidth, MountainsInfo.biHeight, AlphaUsage);
    	DebugTest[3] = AlphaBlend(HDCBack, Mountains.XMain, Mountains.YMain, MountainsInfo.biWidth, MountainsInfo.biHeight, HDCBitmap, 0, 0, MountainsInfo.biWidth, MountainsInfo.biHeight, AlphaUsage);
    	
    	// AlphaBlend(HDCBack, 4, 112, 1024, 128, HDCScreen, 0, 0, 1024, 128, AlphaUsage);
    	
    	DrawDibDraw(ImageHandle, HDCBack, Logo.XMain, Logo.YMain, LogoInfo.biWidth, LogoInfo.biHeight, LogoInfoPointer, LogoDataPointer, 0, 0, LogoInfo.biWidth, LogoInfo.biHeight, 0);
    	DrawDibDraw(ImageHandle, HDCBack, 640, 0, RightSidePanelInfo.biWidth, RightSidePanelInfo.biHeight, RightSidePanelInfoPointer, RightSidePanelDataPointer, 0, 0, RightSidePanelInfo.biWidth, RightSidePanelInfo.biHeight, 0);
    	DrawDibDraw(ImageHandle, HDCBack, 0, 480, BottomSidePanelInfo.biWidth, BottomSidePanelInfo.biHeight, BottomSidePanelInfoPointer, BottomSidePanelDataPointer, 0, 0, BottomSidePanelInfo.biWidth, BottomSidePanelInfo.biHeight, 0);
    	
    	BitBlt(HDCScreen, 0, 0, WindowSizeBase.x, WindowSizeBase.y, HDCBack, 0, 0, SRCCOPY); // swaps the back and front buffers for displaying
    	
    	/*
    	if (DebugTest[0] == 0)
    	{
    		DebugTest[0] = 1; // so this test is processed only once
    		DebugTest[5] = GetLastError(); // shows 87 as the error code
    		
    		sprintf(DebugDetails, "The resulting values are:\n%d\n%d\n%d\n%d\n%d.", DebugTest[1], DebugTest[2], DebugTest[3], DebugTest[4], DebugTest[5]); // for debugging
    		MessageBox(hwnd, DebugDetails, "Debug Results", MB_OK);
    	}
    	*/
    }
    This is all that changed, and their relative positions. For the debug test things, test 1 and test 2 both show a nonzero value. Test 3 shows 0 indicating failure. Test 4 is unused and test 5 shows 87. What parameter is invalid?

  4. #34
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    I don't see any obvious error here. Are you sure you initialized MountainsMainInfo?
    Also you can maybe check if the returned HBITMAP is not NULL.

    Edit: you already checked for a valid bitmap handle I see. Only thing I can think of now is that you forgot to initialize the BITMAPINFO.
    Last edited by pronecracker; 04-17-2007 at 12:39 PM. Reason: have to learn to read someone's posts:P

  5. #35
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    The only thing uninitialized with Bitmapinfo is the same thing that bothered me before and you told me it was fine like that - bmiColors. What do I put there? It seems as if I must use RGBQuad, but what do I use for it? Will it change all the pixels to white if I used 255's? I want the image to be displayed as is (outside adjusting it for fog only (intensity and color), of which I already know how to do this - I've done it since 2003).

  6. #36
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    This is what I did, which makes the unused values zero (instead of uninitialized):

    Code:
            BITMAPINFO bmi = 
            {
                {
                    sizeof (BITMAPINFOHEADER),
                    this->nWidth, bTopDown ? -this->nHeight : this->nHeight,
                    1, 32,
                }
            };    
            this->hBmp = CreateDIBitmap(hCompDC, &bmi.bmiHeader, CBM_INIT, pPixelData, 
                                        &bmi, DIB_RGB_COLORS);

  7. #37
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    (that bTopDown just has to do with supporting both top-down and bottom-up TGA files)

  8. #38
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    Seeing your original code, it's pretty logical that you saw the same image twice, because you copy an area from your window and blend it to the back buffer.

    I'll stop now, tomorrow I'll probably be back.

  9. #39
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    I always use bottom-up TGA files. It matches BMPs and it helps keep consistency. Adding RGBQUAD causes the compiler to error saying:

    c:\my documents\my programs\interactive animation\interactive animation\interactive animation.c(497) : error C2440: '=' : cannot convert from 'RGBQUAD' to 'RGBQUAD [1]'

    Why am I getting this? The documentation doesn't have the [1] at the end....

  10. #40
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    The [1] doesn't mean that it's only one RGBQUAD, it's a trick to store an array of colors with variable length. It's meant to allocate it like this:
    BITMAPINFO* pBmi = (BITMAPINFO*) malloc(sizeof (BITMAPINFOHEADER) + n * sizeof (RGBQUAD));
    Then, you can access the colors [0] to [n-1].
    But again, you don't need this because you are using 32 bits colors.

  11. #41
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    Now that you have created a bitmap object and made sure it is valid (I hope you have), maybe you could first try a simple BitBlt to draw the image without transparency?
    If BitBlt also fails, there's something wrong with the bitmap or the memory DC.

  12. #42
    Registered User pronecracker's Avatar
    Join Date
    Oct 2006
    Location
    netherlands
    Posts
    158
    And could you show me the code that initializes the BITMAPINFO in the WinMain function?

  13. #43
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    Well, basically, here's the code that I have for this:

    Code:
    BLENDFUNCTION AlphaUsage;
    HDC HDCBitmap; // DC for bitmaps
    RGBQUAD RGBColors;
    
    unsigned char MountainsData[524288]; // The mountains background
    LPVOID MountainsDataPointer;
    BITMAPINFO MountainsMainInfo;
    BITMAPINFOHEADER MountainsInfo;
    LPBITMAPINFOHEADER MountainsInfoPointer;
    HBITMAP MountainsBMPHandle;
    struct SceneryData Mountains;
    
    // in the "InitializeDrawing" function
    	HDCScreen = GetDC(hwnd); // set the screen buffer DC
    	HDCBack = CreateCompatibleDC(HDCScreen); // create a compatible DC, of which is to be used for drawing into the back buffer
    	HBMPBack = CreateCompatibleBitmap(HDCScreen, 800, 600); // create compatible bitmap, used for drawing into, but not on screen
    	SelectObject(HDCBack, HBMPBack); // select the created bitmap
    	ImageHandle = DrawDibOpen(); // set the DrawDib DC handle
    	AlphaUsage.BlendOp = AC_SRC_OVER;
    	AlphaUsage.BlendFlags = 0;
    	AlphaUsage.SourceConstantAlpha = 255;
    	AlphaUsage.AlphaFormat = AC_SRC_ALPHA;
    	RGBColors->rgbBlue = 255;
    	RGBColors->rgbGreen = 255;
    	RGBColors->rgbRed = 255;
    	RGBColors->rgbReserved = 0;
    	HDCBitmap = CreateCompatibleDC(HDCScreen); // for AlphaBlend
    	MountainsMainInfo.bmiHeader = MountainsInfo;
    	MountainsMainInfo.bmiColors = RGBColors;
    	MountainsBMPHandle = CreateDIBitmap(HDCScreen, &MountainsMainInfo.bmiHeader, CBM_INIT, MountainsData, &MountainsMainInfo, DIB_RGB_COLORS);
    	SelectObject(HDCBitmap, MountainsBMPHandle); // select the created bitmap
    The InitializeDrawing function is called within the WinMain function, just before the main loop. The RGBQUAD element is causing the compiler to error.

  14. #44
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by ulillillia View Post
    I always use bottom-up TGA files. It matches BMPs and it helps keep consistency.
    You can use a top-down bitmap in Windows, you just have to set the height to a negative value to make it happen.

  15. #45
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    Of course I know that, but some functions, like alpha blend, will not work when height is negative. The main thing is that it matches BMP files which otherwise helps keep the consistancy in style and retain maximum support. If I want bottom-up coordinates instead of top down (as most graphics edittors use), just take the image height, then subtract the coordinate and 1 extra. The coordinate (0, 255) on a 256x256 image is the bottom left pixel. 256 minus 255 gives 1 but the actual position is 0. It's simple math at about the 4th grade level.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 32 bit color depth bitmap problem with XP
    By kalabala in forum C++ Programming
    Replies: 0
    Last Post: 12-22-2008, 06:56 AM
  2. binary numbers
    By watshamacalit in forum C Programming
    Replies: 4
    Last Post: 01-14-2003, 11:06 PM
  3. 16 bit or 32 bit
    By Juganoo in forum C Programming
    Replies: 9
    Last Post: 12-19-2002, 07:24 AM
  4. 32 bit or 16 ???
    By GiraffeMan in forum C Programming
    Replies: 11
    Last Post: 04-24-2002, 12:56 PM
  5. Array of boolean
    By DMaxJ in forum C++ Programming
    Replies: 11
    Last Post: 10-25-2001, 11:45 PM