Title: WELL COMMENTED display bitmap tut/ex
Description: anyone know of one?
TheHawgMaster - December 19, 2003 11:47 PM (GMT)
DrVoodoo:
| QUOTE (Myself) |
| (at least games :lol:) |
And I dunno bout the stretchblt thing, my video hardware absolutely loves scaling (it blends pixels flawlessly at virtually any size with little performance penalty) so my computer probably is an exception to the rule... with most computers it might be slower. (then again I haven't done a benchmark on mine for a while so I could have just been wrong the whole time here...) Anyway there isn't really any reason to argue about it :)
ih8censorship - December 14, 2003 04:24 PM (GMT)
does anyone know of a well commented display bitmap example? i found a few examples but there is like no comments and i have no clue how exactly it works, but it looks like something i can do if i knew how it actually works other than just an uncommented code snippet.
dr voodoo - December 14, 2003 06:56 PM (GMT)
One way to draw a bitmap is using the GDI. First you get a HDC with the GetDC function next you create a compatible HDC with CreateCompatibleDC. Now you load the bitmap with LoadBitmap. You select the bitmap with the SelectObject function into the HDC created with CreateCompatibleDC. And now you use BitBlt to draw form one HDC to the other. When this is done you must not forget to clean up. This is done with ReleaseDC for the HDC you got with GetDC. DeleteDC for the other one and DeleteObject for the bitmap.
TheHawgMaster - December 14, 2003 10:08 PM (GMT)
| QUOTE |
| Now you load the bitmap with LoadBitmap |
You should load the bitmap with LoadImage
| QUOTE |
| now you use BitBlt to draw form one HDC to the other |
StretchBlt is both faster and more powerful then BitBlt.
Bodach - December 18, 2003 02:24 AM (GMT)
| QUOTE |
| StretchBlt is both faster and more powerful then BitBlt. |
More flexible, yes but faster, no - BitBlt is quicker. :)
| QUOTE |
| does anyone know of a well commented display bitmap example? |
I think
this one by Sunlight seems fairly clear, although it's pitched specifically at msvc users. You may also be interested in working though some of
GameTutorials winapi gdi bitmap examples, although again the source is pitched at msvc (.net) users.
TheHawgMaster - December 18, 2003 11:02 PM (GMT)
| QUOTE |
| More flexible, yes but faster, no - BitBlt is quicker |
Really? I've always found it to be faster but it probably depends on your comp. Besides, you typically end up using StretchDIBits or some even more flexible function in real life applications (at least games :lol:)
dr voodoo - December 19, 2003 09:53 AM (GMT)
| QUOTE |
| you typically end up using StretchDIBits or some even more flexible function in real life applications |
Up to now I have always used BitBlt.
Bodach - December 19, 2003 08:37 PM (GMT)
| QUOTE |
| Really? I've always found it to be faster but it probably depends on your comp. |
Sorry, I can't seem to find anything more than anecdotal evidence (for example,
this ) on the web but I know that StretchBlt calls BitBlt internally if the image and destination dimensions are the same. Might be an idea to test them by timing the functions and see which performs better.... :)
Bodach - December 20, 2003 12:55 AM (GMT)
| QUOTE |
| Anyway there isn't really any reason to argue about it. |
Please forgive me if I appear argumentative - i'm simply enjoying an interesting discussion. :D
ih8censorship - December 20, 2003 04:10 PM (GMT)
allright today i am focusing on getting a bitmap drawn. heres what i have:
global variables:
| CODE |
HBITMAP pic; HDC hdc; HDC comp; |
right at the begining of winmain
| CODE |
| pic=LoadBitmap(hThisInstance,"hello.bmp"); |
WM_CREATE
| CODE |
hdc=GetDC(hwnd); comp=CreateCompatibleDC(hdc); SelectObject(comp,pic); |
WM_PAINT
| CODE |
BitBlt(hdc,10,10,100,100,comp,20,20,BLACKNESS); ReleaseDC(hwnd,hdc); DeleteDC(comp); DeleteObject(pic); |
and all im getting is a black square, which isnt the bitmap "hello.bmp" but its better than what i got when i tryed before which was nothing....
Bodach - December 20, 2003 04:27 PM (GMT)
Change 'BLACKNESS' (which is why you're getting a black square) to 'SRCCOPY' in the BitBlt call and you should see your bitmap. :)
ih8censorship - December 20, 2003 04:59 PM (GMT)
well when i tryed replacing "blackness" with "SRCCOPY" then i couldent see anything.... could the intergers in my bitblt function have anything to do with it?
**edit** i put
| CODE |
if(!pic) MessageBox(0,"failed to load image","error",MB_ICONERROR|MB_OK); |
right under where i tryed to load the bitmap and the error poped up. so the reason i cant see an image must be cause the image isnt loading correctly... right?
TheHawgMaster - December 20, 2003 06:43 PM (GMT)
I've always thought it was a little odd that the 'BLACKNESS' option even existed... Isn't that what the 'Rectangle' funciton is for?
dr voodoo - December 20, 2003 07:01 PM (GMT)
| QUOTE |
right at the begining of winmain
| CODE | | pic=LoadBitmap(hThisInstance,"hello.bmp"); |
WM_CREATE
| CODE | hdc=GetDC(hwnd); comp=CreateCompatibleDC(hdc); SelectObject(comp,pic); |
WM_PAINT
| CODE | BitBlt(hdc,10,10,100,100,comp,20,20,BLACKNESS); ReleaseDC(hwnd,hdc); DeleteDC(comp); DeleteObject(pic); |
and all im getting is a black square, which isnt the bitmap "hello.bmp" but its better than what i got when i tryed before which was nothing....
|
I normaly do drawing not in a WM_PAINT message but in a WM_TIMER message. I load the resources right before the message loop and do clean up after the message loop before the the return statement. So my code normally looks something like this:
| CODE |
HDC win_dc,map_dc; HBITMAP map_bit; WinMain(...) { //register & create window win_dc=GetDC(hwnd); map_dc=CreateCompatibleDC(win_dc); map_bit=LoadBitmap(hThisInstance,MAKEINTRESOURCE(bitmap_id)); SelectObject(map_dc,map_bit); SetTimer(hwnd,1,1000,0); //message loop DeleteDC(map_dc); ReleaseDC(hwnd,win_dc); DeleteObject(map_bit); return 0; } //call back function WM_TIMER: if(wParam==1) BitBlt(win_dc,10,10,100,100,map_dc,0,0,SRCCOPY); break; |
| QUOTE |
| could the intergers in my bitblt function have anything to do with it? |
They indicate width&height, x&y in the window and x&y in the bitmap. If none of them is bigger than your actual surface (example if window width=200 and you draw at x=300 you wont see anything).
| QUOTE |
| so the reason i cant see an image must be cause the image isnt loading correctly... right? |
Yes, check if your bitmap exists in the same dir as the exe. I can't help much on loading files because I have, up to now, always done it with linked bitmaps.
ih8censorship - December 20, 2003 09:31 PM (GMT)
well i dont think its the second parameter in loadbitmap because that file exists where my exe does...so it means it must be the first one.from msdn about the first parameter:
| QUOTE |
hInstance
Identifies the instance of the module whose executable file contains the bitmap to be loaded.
|
now maybey im using the wrong HINSTANCE..... im using it like
| CODE |
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) |
and my window structure deal has
| CODE |
| wincl.hInstance = hThisInstance; |
so i sure thought that parameter would be hThisInstance....... anymore ideas on what im doing wrong just post please :D
oh btw, how do i use resource files to make my image then? MAKEINTRESOURCE kinda confuses me a bit... maybey that will help
***edit*** well looked around and the site Bodach said had a function on it
| CODE |
HBITMAP LoadBitmapFile(const TCHAR *filename) { return (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); } |
and i used that instead of loadbitmap and everything worked fine. now, why dident it before :huh:
Bodach - December 20, 2003 10:46 PM (GMT)
| QUOTE |
| oh btw, how do i use resource files to make my image then? |
Ahhhh! I thought you were using resources already. That changes things a bit. ;) :D
If you're going to load an image from file then use
LoadImage, for example:
| CODE |
char filename[]="image.bmp"; pic=(HBITMAP)LoadImage(0, /*going to load directly from file*/ filename, IMAGE_BITMAP, /*type of image to load*/ 0, /*use the image width*/ 0, /*use the image height*/ LR_LOADFROMFILE | LR_DEFAULTCOLOR); |
should load your image directly from file but note that if you're running your app from within the ide of msvc then the bitmap needs to be in the project directory (you could always use an absolute path to the bitmap file to be certain).
If you need to get the dimensions of the bitmap once it's loaded then
GetObject is useful, eg:
| CODE |
BITMAP bm; int height,width; GetObject(pic, /*gdi object - your bitmap or whatever */ sizeof(BITMAP), /*physical size of structure*/ &bm); /*where GetObject stores object information */ height=bm.bmHeight; width=bm.bmWidth;
|
If you would rather use resources instead of loading the bitmap directly from a file then let us know which compiler you are using because there are some differences in how to go about this depending on the compiler.
ih8censorship - December 20, 2003 11:05 PM (GMT)
well yeah i did get it to load from the file, but someday i may actually get good at graphics (doubtfull) and might want to include them right in the exe. is that done with resources then? i have both vc++ and devc++ with mingw so information on loading from resources for both of them would be great, because yeah someday i might want to do that if i make a decent image :lol:
Bodach - December 20, 2003 11:19 PM (GMT)
| CODE |
| is that done with resources then? |
Yes. :)
For msvc there's a built in GUI resource editor. I think the options are Project menu, select add resource (it might be 'insert'). This should pop-open a dialog, select bitmap and import.... Just accept the default id for your bitmap (IDB_BITMAP1). You might have to add the resources to your project which you do from the project menu, select add to project (or add existing), select the *.rc and resource.h file and add them to your project. You should now have an extra 'resources' tab on the project view within the ide.
To use the resource(s) you have to include the resource.h header file in any code file that will be using it. Use the id with MAKEINTRESOURCE to get your bitmap, eg:
| CODE |
#include "resource.h" /* your code */ /*load the bitmap*/ HBITMAP pic=LoadBitmap(GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP1)); |
TheHawgMaster - December 22, 2003 05:02 AM (GMT)
You are obviously unaware of the great GetBitmapDimensionEx
Bodach - December 22, 2003 01:52 PM (GMT)
| QUOTE |
| You are obviously unaware of the great GetBitmapDimensionEx |
Yes, I was completely unaware of it - thankyou very much indeed for introducing us. ;) :D
But I wouldn't use it anyway because:
- The retrieved dimensions must have been set by the SetBitmapDimensionEx function. (from msdn description).
- It only retrieves the dimensions of a compatible bitmap.
- Even when I tested it raw (LoadBitmap/LoadImage on resource bitmap) it failed to provide any useful information - it zeroed the SIZE struct. The function seemed to work correctly because it returned a non-zero value indicating successful execution.
I may be using it wrong, though, so would appreciate an example of its proper usage if you have the time. :)
Thanks again for letting me know about it. :)
TheHawgMaster - December 22, 2003 10:07 PM (GMT)
I've never used it before either actually (I've always used the approach you mentioned above), I had just heard about it a long time ago and was pointing out it's existence :)
alionline759 - January 14, 2004 10:33 AM (GMT)
If you want cntact to me to guide you