Announcement

Collapse
No announcement yet.

CopyBitmapEx in Source code forum

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • james klutho
    replied
    Thanks for the compliment Chris. I saw a reference to PlgBlt on the web and remembered Patrice's PlgBlt code posted sometime back. My update demo using PlgBlt went together fairly easily- this exercise is more of a curiosity to me. I know nothing about DIB sections. Maybe at some point I will learn but not now. Your sprite engine sounds impressive.

    Leave a comment:


  • Chris Boss
    started a topic CopyBitmapEx in Source code forum

    CopyBitmapEx in Source code forum

    I didn't want to discuss this in the source code forum, so I posted this thread for that.

    James Klutho posted a nice sprite animation sample which uses PlgBlt here:

    http://www.powerbasic.com/support/pb...740#post357740

    The question of performance (speed) will always come up when one first starts writing this kind of code.

    I tested it out (changed it to 24 sprites) and I got 33 fps and with Alphablending I got 11 fps.

    I needed some way to benchmark the code, so of course I have my own code to compare it to (which is the only reason I mention it here).

    Now you may wonder how my Sprite code gets about 65 fps and 40 fps (alphablending) with the same number and size sprites ?

    Now I can't give away any proprietary secrets, but this much I can tell you is that this demonstrates the difference between using GDI calls and using DIB Sections and writing low level code (assembler if you can handle it, pointers if you are not a assembler guru). Now I don't use any assembler right now, so if I did I could even get more speed out of DIB's, but even with pointers one can get very good performance.

    I have mentioned DIB Sections a number of times on the forums, but this is a real life example of the difference in performance.

    DIB 101:

    Now I should point out that the PB GRAPHIC GET / SET BITS commands are not DIB Sections so you can't emulate them using PB commands. You must use the API. GRAPHIC GET/SET BITS is inherently slow compared to DIB sections. Why ?

    It requires twice as much memory (you have the bitmap and a memory buffer the same size to move the pixels to) and it requires 3 times as much work, since there are three steps, copy pixels to buffer, modify pixels and then copy pixels back to the bitmap.

    If you are looking for performance, you need to use real DIB sections.

    DIB sections are actually one of most powerful graphic tools in the Windows API and they have been around since Windows 95. The only better performance you will get over DIB's is when you switch to hardware supported graphics (ie. OpenGL or DirectX).

    DIB's are at the core of the Windows video API's (DRAWDIB functions).

    DIB's work well on Windows 95 up to Windows 7 too.

    Some info about DIB's which may be useful for those who would like to experiment with them:

    Avoid 16 or 24 bit DIB's. They require more complex memory handling since if a row does not come out to an exact division of 4, then it must be padded with extra bytes.

    32 bit DIB's never need padding because each pixel is 4 bytes.

    By default DIB's are upside down (first pixels are bottom row on screen). You can define a negative height for the DIB to convert it to a right side up DIB, which is what I prefer. I don't know if there is a performance hit for doing that though.

    Be careful of using some of the DIB code on the forums, since a good bit of it makes an error in treating a DIB handle as if it was a global memory handle (which it is not) and you may see the code use calls to GLOBALLOCK. You don't Lock a DIB's memory before accessing it. You never use GLOBALLOCK with a DIB handle.

    Another very important thing to note about DIB's is that you never mix GDI drawing with direct memory access of the DIB at the same time. You can use the GDI on a DIB just like a normal bitmap (even select it into a DC), but when you finished using the GDI, before you access the DIB's pixels directly you must always call the GDIFlush API function first.

    You also need to know the format of the pixels in a 32 bit DIB.

    I used the following type:

    Code:
    TYPE DIB_RGB32
        B   AS BYTE
        G   AS BYTE
        R   AS BYTE
        Reserved AS BYTE
    END TYPE
    Notice the order is BGR and not RGB.

    The reserved byte is technically for alphablending, but BitBlt does not deal with that byte. The AlphaBlend API function though does deal with the alpha (reserved) byte, but I should warn you it does not work the way you expect. AlphaBlend requires precalculating the value of the alpha byte, so read the API docs carefully.

    You can use DIB's for part of your work or use a DIB for 100% of it. I don't use any GDI calls at all when drawing on DIB's. I do all my drawing in multiple DIB's and then the final image is BitBlt to the screen.

    If you use say AlphaBlend I am not sure whether you will get the same speed as you would as you would if you write your own alphablending code. I use a proprietary engine which does a number of tricks I have not mentioned here.
    Last edited by Chris Boss; 28 Nov 2010, 09:17 PM.
Working...
X