Hey All i noticed there was no tutorial on this forum for BiBlt so here one I made (please note this was origionally made for another forum, but i began to dislike using it so i came here )
Comments and improvements are welcome
So you want to learn BitBlt but dont know where to start? Well hopefully this tutorial will get you on the road to becoming a BitBlt master
So what is BitBlt?
Well BitBlt is one of many windows API's
Getting Started
So lets jump right in and get some coding done
Ok first things first open up a new VB project and we are going to add a module, name it 'mdlBitblt' and name the form 'frmbitblt' In the module we are going to place the BitBlt API
so in the module enter the following...
VB Code:
Public Declare Function BitBlt Lib"gdi32" _
(ByVal hDestDC As Long, ByVal X As Long,_
ByVal Y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc _
As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Ok dont be put off bye the way it looks, it looks ALOT harder than it actually is!
Next Stage
So we have the API in place now all we need to do is use it
As you will see I have attached 3 pictures, Hero, Hero Mask, and Land
You will need to draw up 3 picture boxes on your form and call them the following
Hero
HeroMask
Land
Set the 'autoredraw' property to True, and the 'visible' property to false, it is also a good idea to set the 'scalemode' to 3 – Pixels (also set the forms 'scalemode' to pixels)
Ok now into each picture box load its respective image
Next draw 3 command buttons and add the following names and captions –
Name = cmddrawland caption = Draw Land
Name = cmddrawmask caption = Draw Mask
Name = cmddrawhero caption = Draw Hero
BitBlt - is saying we want to use the BitBlt Api, frmBitBlt.hDC - is where we are going to BitBlt to, 50 is the X position on the surface your are BitBlt'ing on 50 is the Y position on the surface your are BitBlt'ing on 300 is the width 300 is the height frmbitblt.land.hDC this is what we are actually going to Copy from 0 and 0 - this is the area of the picture u wish to ‘cut out’ for now don’t worry about this VBSrcCopy - this is the type of bitblt for the background we will just copy it!
You may have noticed this .HDC well heres a definition...
This is an upgrade from previous versions of Visual Basic which allows you to interface with the windows api functions. You will find it on certain controls and all forms as the property .hdc or even hWnd.
The term hdc is the handle to the device context of that window or control.
The Hero Mask Code
And Now we will draw our Hero Mask....
But what is a mask? Well a mask in terms of BitBlt is basicly a copy of the actuall image, in our case all black, which we put on the background first to stop the background colours leaking through and spoiling our image
VB Code:
Private Sub cmdDrawmask_click()
drawMask ' this will go to the ‘drawMask’ sub in the module
Again this time we have vbSrcPaint which is what we use for painting on top of the mask!
Please make a note to the fact that the hero mask X and Y position must be exactly the same as the Hero’s X and Y
And that’s it I hope you have now begin to understand how powerfull BitBlt can be
I have also made an example in the Zip file below
‘Good Luck’
PINO-
Please note the image of the 'hero' is not made by me, i found while searching, if you are the owner and do not wish me to use it then please say and i will remove it
Ok hey again, i'm a little stuck with what to do, so if anyone would like to see and advance on this tuturiol or maybe you have something you need to be explained please reply, i cant think as of yet a tuturiol to write
I read your explanation and downloaded your tutorial codes and ran it. I got a problem here.
I had a little piece of software running, after mask or land or hero have been drawn on the form, I moved the software around and whenever it covered the picture area, the picture was erased by the software's interface.
Or when I minimize the form and brougt it up again, image on the form disappeared
Ok... I am a student who just learned this semester (about 4 months ago and up until now) how to program in VB. I don't know much about bitblt and neither does anybody that I know, but I did get it to work on a project that I am working on and have been working on for like... 3 months. However, there are some slight defects...
My project includes an image of a ship at the bottom of the screen, that a player can move back and fourth. The player also may shoot up at enemy ships hovering between it and the top of the screen. The enemies shoot back. Everything is made out of images (not pictureboxes).
When I tried to use bitblt to make my ship be something other than a box, I was unsuccessful at first. I kept trying and eventually got that to work, and the ship was no longer flickering occasionally. Then the enemies and everything else started flickering like crazy !
I tried solving my problem by using bitblt on the enemies as well ... That only resulted in either no enemies at all and just my ship, only one enemy, or nothing at all ... I mean like... What's up with that?? I have been looking around for a while for a solution, and have not found any help. If anybody knows how to fix this then PLEASE respond to this
I read your explanation and downloaded your tutorial codes and ran it. I got a problem here.
I had a little piece of software running, after mask or land or hero have been drawn on the form, I moved the software around and whenever it covered the picture area, the picture was erased by the software's interface.
Or when I minimize the form and brougt it up again, image on the form disappeared
Have an idea why?
Check some of the "AutoDraw" boolean's of the picture boxes you use
Hi! I got like 80 pictures in my animaton. I can't use like 80 picture boxes o_O
Help...
For the main images create a picture box. Adjust the properties to fit your needs and then set the index property to 0.
For my example the name will be picMain. I'm also assuming all the frames for the pictures will be located in the same directory your project is in, and that they will be named 1.gif, 2.gif, 3.gif , ect.
Then you can use the load statement to create 80 more picture boxes.
Dim i As Integer
VB Code:
For i = 1 To 80
Load picMain(i)
picMain.picture = LoadPicture(app.path & "\" i & ".gif")
Next i
Then you can do the same thing for the mask. I haven't tested this code but by all means it should work.
If I can make you guys a suggestion - setting the destination's autoredraw property to true can become a plague to your resources and your refresh rate will fall if you are doing animations.
Experiment with getting all bitblt'ing done in the 'form_paint' procedure with autoredraw=false
To help a little more - don't bitblt (or others like stretchblt, all related ops including setpixel) to the output hDC, this is ugly with flickering and other nonsense once you get a frame rate happening. Make a buffer, if you don't know how to use API calls to make a bitmap buffer which doesn't rely on a form or other container then just load a form at the size you want to make your output display, load the form and .hide it.
Get the hidden form's hDC, this is your buffer - draw everything into the buffer then try an edit of the following code in your form's "form_paint" routine:
Code:
Private Sub form_paint()
BitBlt Viewer.DC, FormXoFf, FormYoFf, Buffer.w, Buffer.h, Buffer.DC, 0, 0, SRCCOPY
End Sub
Secondly - double buffer it so that no ugliness may reach the output pane under any circumstance, this means build the frame/snapshot into buffer1, copy buffer1 to buffer2 everytime the frame is completed and then any/every time that the 'form_paint' routine is called it will be drawing a complete frame onto the output page instead of potentially being called from time to time with a half drawn buffer (more flickering effect if so).
** by memory (while since I bothered with this stuff), it is necessary to call 'form_paint' in the code directly after copying the completed buffer1 to buffer2, no need to sense focus or anything else because (while autoredraw=false) 'form_paint' is called not only on focus and resize, but also whenever other forms are dragged, resized or in any way moved in such a way as to reveal a part of 'our' form.
Experiment with it, try to trust me that autoredraw on the output pane is ugly and slow, egdemeal's idea of setting the picture to it's image is ok if you are not trying to do a lot of clever graphics at a decentish/high frame rate - pretty sure it's overhead on the CPU that could be better spent.
Just in case you are wondering what makes me think I understand these things, please go and look at my old crap that I wrote before learning that 'form_paint' is the best place to 'paint the form' (LOL!), I did alright and the three frame/rate animation games I am hosting at www.robsfreespace.com/free_basic_games all use bitblt and all are written by me.
*** I read somewhere that the 'form_paint' procedure runs in the best way possible for outputting graphics, all to do with timing and interrupts - I thought it was bulldust but experiments made it clear that I could get a better frame rate on worse CPUs by using it in certain ways - experiment.
Regards,
robsoles.
Last edited by robsoles; Jan 6th, 2008 at 12:11 AM.
I've got a funny feeling you don't want to chew up all the resources that 80 pictureboxes would, an alternative is to assemble the pictures onto a single bitmap in an organised way and then pick them out with mathematics, grab mazeracer off me - http://www.robsfreespace.com/free_basic_games/mazeracer - and take a look at the single bitmap (..\gamebits.bmp) which has all the graphics I use in the game, including the background(s).
- edit: Oops, should mention that the masks for the ships are all generated from the bitmap in the first second or so of being executed.
Last edited by robsoles; Jan 6th, 2008 at 12:47 AM.
hi, u mentioned that you're a bit stuck on what to do next...
i'm in need of a tutorial explaining how to make tile-based maps using a text file... n e idea how to do it, or can you nudge me in the right direction?
Ok, but.......
To get to the result the example produces, it's a lot more simple to just put an Imagebox with the island and over it a Imagebox (transparent gif) with the hero. A LOT more simple.
So what can you really do with BitBlt that you can't by just working with transparent gif?
Ok, but.......
To get to the result the example produces, it's a lot more simple to just put an Imagebox with the island and over it a Imagebox (transparent gif) with the hero. A LOT more simple.
So what can you really do with BitBlt that you can't by just working with transparent gif?
Have you tried using that for a full game? Lots of bullets on the screen lots of sprites? Using the method you just described your app would come crashing down. So speed is the main thing.
You also have a lot more control on what part of the sprite you show. Essentially if your writing a game BitBlt should be the minimum and DirectX the ideal.
Thank you, Pino.
Oh, now I get it: BitBlt is like GET - PUT in QuickBasic!
And it's 100% flickering-proof, right?
I know the thread is very old, but I haven't found any step-by-step tutorial on BitBlt (What it is, what for, why one should use it, why one shouldn't use it, etc).
As you will see I have attached 3 pictures, Hero, Hero Mask, and Land
Sorry for intruding again, I'd hate to be an pain in the *** in my very 2nd BitBlt day, since you're on it at least since 2003.
I just realized something it may be intresting: there is no need for the mask to be black & white. The mask perfectly can be the same coloured Hero but with white background.
What i'm saying this for? 'Cause it's much more simple just to paint the background. (i.e, you do the mask with just 1 click, even with MsPaint).
Please do not post questions in CodeBank threads unless they are about the actual code that is shown - for other questions on the topic you should create your own thread, which you already had in this case: how to print the bitblt image