Thread: Using DrawDibDraw

  1. #1
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582

    Using DrawDibDraw

    An important thing with making games (or nearly any program) are graphics. I've been looking through the "Microsoft Platform SDK" for details on how do add graphics to my learner's test Windows program. It appears as if I need to use DrawDibDraw to do this. I'm confused about 4 things with it.

    The first two elements involve a handle. The first is to the DrawDib DC and the second to the DC. What is a handle in C programming? In my other tool I used, it was a variable, but since C has multiple types of variables, which do I use if this is the case?

    The second involves two otherwise identical parameters occurring twice. xDst and xSrc appear to be exactly the same thing (along with the y values). What is the difference between these? The other involves dxDst and dxSrc (and the y values as well). Whare are the differences between these?

    The third involve the two pointers. What is this "bitmap info header" thing? The second involves a pointer to a buffer. What is a buffer and how is one set up?

    I understand the file format of BMP files so that's not the issue (as I can open such a file). The types of files I use are 24 and 32-bit files (TGA used if 32-bit, the most common). I'm trying to display a 512x384 test image as a 24-bit color BMP image. As far as I can tell, I'd have something like this:

    DrawDibDraw(???, ???, 64, 48, 512, 384, ???, ???, 64, 48, 512, 384, NULL);

    This would center the 512x384 image in a 640x480 window (interior space - borders and the title bar add extra) and I don't seem to need any of the flags. Those with ??? are where I'm confused with and there seems to be a duplicate series due to the second issue.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you should look for some sample for example:

    http://lists.helixcommunity.org/pipe...st/000568.html
    first argument is HDD handle that you initialize by the DrawDibOpen and use in all subsequent calls to DrawDib functions

    The second argument is HDC of the window your going to draw on.

    The two more ??? are representing the pointor to BMP header info structure that should be filled with the BMp parameters info
    and pointer to the buffer containing the data to be drawen
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    HANDLES are a type of pointer.

    The Dst is 'destination' and Src is 'source' image / Device context.

    I would run a search here for 'double buffering' or GDI. There is plenty of code already posted to draw bmps to the screen.

    I would look at CreateCompatibleBitmap(), BitBlt(), SelectObject() ect.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  4. #4
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    So I've been looking around for details but there seems to be some issues.

    Code:
    // First Windows app.cpp : Defines the entry point for the application.
    /*
    To do before making the first useful Windows application - what background scaling is (or "The Supernatural Olympics" version 1.1):
    Draw images
    Syncronize drawing images with monitor refresh rate
    Call a function upon pressing a key
    */
    
    /*	Trim fat from windows*/
    #define WIN32_LEAN_AND_MEAN	
    #pragma comment(linker, "/subsystem:windows")
    /*	Pre-processor directives*/
    #include "stdafx.h"
    #include <stdio.h>
    #include <windows.h>
    
    // defines and global vars
    #define x 0
    #define y 1
    
    short screen_size[2]; // screen resolution (e.g. 1920x1440)
    short window_size_base[2]; // expected window size
    short window_size[2]; // actual window size
    short window_pos[2]; // window position
    short title_bar_height; // height of the title bar in pixels
    short window_border[2]; // size of the window border
    
    int file_handle; // handle for reading/writing files
    char bmp_image[]; // data for the bitmap image
    
    int *img_handle; // pointer for a handle
    int *HDC_handle; // pointer for HDC handle
    
    BITMAPINFOHEADER bmp_head;
    
    void draw_test_image()
    {
    	img_handle = DrawDibOpen();
    
    	file_handle = fopen("C:\\My Documents\\My programs\\ulillilliacity.bmp", "rb"); // read the source BMP file to display, binary mode
    	fseek(file_handle, 2, seek_set); // skip the first two bytes, the file identifier, the string "BM"
    	// fill the struct reading from the file
    	fread(&bmp_head.biSize, 4, 1, file_handle); // actual file size
    	// 12 bytes missing here, according to what I'm seeing in the hex edittor
    	fread(&bmp_head.biWidth, 4, 1, file_handle);
    	fread(&bmp_head.biHeight, 4, 1, file_handle);
    	fread(&bmp_head.biPlanes, 2, 1, file_handle);
    	fread(&bmp_head.biBitCount, 2, 1, file_handle);
    	fread(&bmp_head.biCompression, 4, 1, file_handle);
    	fread(&bmp_head.biSizeImage, 4, 1, file_handle);
    	fread(&bmp_head.biXPelsPerMeter, 4, 1, file_handle);
    	fread(&bmp_head.biYPelsPerMeter, 4, 1, file_handle);
    	fread(&bmp_head.biClrUsed, 4, 1, file_handle);
    	fread(&bmp_head.biClrImportant, 4, 1, file_handle);
    	fread(&bmp_head.biClrImportant, 4, 1, file_handle);
    	fread(&bmp_image, 1, bmp_head.biSizeImage, file_handle); // read the remainder of the bits, the image data part
    	fclose(file_handle);
    	
    	DrawDibDraw(img_handle, hDC, 64, 48, 512, 384, bmp_head, bmp_image, 64, 48, 512, 384, 0); // still not sure about the first group of numbers
    	DrawDibClose(img_handle); // free the resources
    }
    
    /*	Windows Procedure Event Handler*/
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	PAINTSTRUCT paintStruct;
    	/*	Device Context*/
    	HDC hDC; // is this the DC declaration?
    	/*	Text for display*/
    	char string[] = "Image test - there should be an image below"; 
    	/*	Switch message, condition that is met will execute*/
    	switch(message)
    	{
    		/*	Window is being created*/
    		case WM_CREATE: 
    			return 0;
    			break;
    		/*	Window is closing*/
    		case WM_CLOSE: 
    			PostQuitMessage(0);
    			return 0;
    			break;
    		/*	Window needs update*/
    		case WM_PAINT: 
    			hDC = BeginPaint(hwnd,&paintStruct);
    			/*	Set txt color to blue*/
    			SetTextColor(hDC, COLORREF(0x00FF8040));
    			/*	Display text in middle of window*/
    			TextOut(hDC,0,2,string,sizeof(string)-1);
    			EndPaint(hwnd, &paintStruct);
    			return 0;
    			break;
    		default:
    			break;
    	}
    	return (DefWindowProc(hwnd,message,wParam,lParam));
    }
    /*	Main function*/
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    	WNDCLASSEX  windowClass;		//window class
    	HWND		hwnd;				//window handle
    	MSG			msg;				//message
    	bool		done;				//flag saying when app is complete
    	/*	Fill out the window class structure*/
    	windowClass.cbSize = sizeof(WNDCLASSEX);
    	windowClass.style = CS_HREDRAW | CS_VREDRAW;
    	windowClass.lpfnWndProc = WndProc;
    	windowClass.cbClsExtra = 0;
    	windowClass.cbWndExtra = 0;
    	windowClass.hInstance = hInstance;
    	windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	windowClass.lpszMenuName = NULL;
    	windowClass.lpszClassName = "MyClass";
    	windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
    	/*	Register window class*/
    	if (!RegisterClassEx(&windowClass))
    	{
    		return 0;
    	}
    	
    	/* SM_CXBORDER is 1
    	SM_CYBORDER is 1
    	SM_CXEDGE is 2
    	SM_CYEDGE is 2
    	SM_CXFIXEDFRAME is 3
    	SM_CYFIXEDFRAME is 3
    	SM_CXSIZEFRAME is 4
    	SM_CYSIZEFRAME is 4
    	SM_CYCAPTION is 18
    	*/
    	
    	window_border[x] = GetSystemMetrics(SM_CXSIZEFRAME); // obtain border sizes, title bar height, and operating resolution
    	window_border[y] = GetSystemMetrics(SM_CYSIZEFRAME);
    	title_bar_height = GetSystemMetrics(SM_CYCAPTION); // obtain height of the title bar
    	screen_size[x] = GetSystemMetrics(SM_CXSCREEN); // operating resolution
    	screen_size[y] = GetSystemMetrics(SM_CYSCREEN);
    	window_size_base[x] = 640; // interior window size
    	window_size_base[y] = 480;
    	window_size[x] = window_size_base[x]+window_border[x]*2; // full window size, including borders and title bar
    	window_size[y] = window_size_base[y]+window_border[y]*2+title_bar_height;
    	window_pos[x] = (screen_size[x]/2)-(window_size[x]/2); // center the window
    	window_pos[y] = (screen_size[y]/2)-(window_size[y]/2);
    	
    	/*	Class registerd, so now create window*/
    	hwnd = CreateWindowEx(NULL,		//extended style
    		"MyClass",			//class name
    		"First Windows app",		//app name
    		WS_OVERLAPPEDWINDOW |		//window style
    		WS_VISIBLE |
    		WS_SYSMENU,
    		window_pos[x],window_pos[y],			//x/y coords
    		window_size[x],window_size[y],			//width,height
    		NULL,				//handle to parent
    		NULL,				//handle to menu
    		hInstance,			//application instance
    		NULL);				//no extra parameter's
    	/*	Check if window creation failed*/
    	if (!hwnd)
    		return 0;
    	done = false; //initialize loop condition variable
    	/*	main message loop*/
    	
    	draw_test_image();
    	
    	while(!done)
    	{
    		PeekMessage(&msg,hwnd,NULL,NULL,PM_REMOVE);
    		if (msg.message == WM_QUIT) //check for a quit message
    		{
    			free(*img_handle);
    			done = true; //if found, quit app
    		}
    		else
    		{
    			/*	Translate and dispatch to event queue*/
    			TranslateMessage(&msg); 
    			DispatchMessage(&msg);
    		}
    	}
    	return msg.wParam;
    }
    These are my issues:
    1. While reading from the BMP file, there seems to be an extra 12 bytes in the file, as seen in my hex edittor (XVI32). The location of the missing bytes is commented where it is found. I saved the 24-bit uncompressed BMP file with "The GIMP".
    2. I want the interior part of the window to be 640x480, which excludes borders, menus, and the title bar. I don't have any menus at the moment though. I also want the window itself to be centered. The method I have works fine, but seems awfully complicated so I'm wondering if there's a better way.
    3. I don't know if I set up the DrawDibDraw function properly, the pointers and handles especially. I'm still confused about the Dst and Src values.
    4. Without the bitmap reading stuff, my program is using 100% of the CPU when all other windows programs barely use any of the CPU. Why is this and how do I fix it? I suspect it has something to do with the while loop in the WinMain function.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Rendering 32-bit images - alpha is ignored
    By ulillillia in forum Windows Programming
    Replies: 59
    Last Post: 04-21-2007, 03:50 PM
  2. DrawDibDraw - Draw into back buffer instead of on screen
    By ulillillia in forum Windows Programming
    Replies: 6
    Last Post: 04-15-2007, 12:49 AM
  3. Is DrawDibDraw thread safe?
    By vart in forum Windows Programming
    Replies: 0
    Last Post: 11-14-2006, 11:53 PM
  4. DrawDIBDraw Problem
    By sunis in forum Windows Programming
    Replies: 1
    Last Post: 12-03-2002, 03:07 AM