Page 2 of 2

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 4:21 am
by StephanvanSchaik
Brendan wrote:Mostly, you should get acceptable results on Bochs (which is much slower than real hardware) in all video modes without any hardware acceleration; and if you don't then your code needs to be optimised more... ;)
I think Bresenham's books and resources might be a good recommendation as well, that is, if you can get your hands on them.


Regards,
Stephan J.R. van Schaik.

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 5:26 am
by Brendan
Hi,
quanganht wrote:You have some really good snipets, Brendan! It would definetely help me alot later. Thanks
Thanks!

Something else I probably should've mentioned is double buffering: if it takes a bit of work to generate a frame of video data, then it's probably faster to generate the frame in (fast) RAM and then copy it to (slower) video display memory in one go. Of course this can be optimised too - keep track of which parts changed, and only send the changed data to display memory.

For a more extreme example (using a pair of buffers in RAM, and a "line changed" flag for each row of pixels):

Code: Select all

void blit_buffer_to_video(void) {
    uint32_t offset = 0;
    void *dest_address = video_display_memory;
    void *temp_dest_address;
    uint32_t next_dword;

    for(y = 0; y < screen_height; y++) {
        if(line_changed_flags[y] != 0) {
            temp_dest_address = dest_address;
            for(x = 0; x < screen_width; x += 4) {
                next_dword = new_buffer[offset];
                if( current_buffer[offset] != next_dword ) {
                    current_buffer[offset] = next_dword;
                    *(uint32_t *)temp_dest_address = next_dword;
                }
                offset++;
                temp_dest_address += 4;
            }
            line_changed_flags[y] = 0;
        } else {
            offset += screen_width;
        }
        dest_address += bytes_per_line;
    }
}
Basically, for each row of pixels that was changed, compare the old data with the new data and only send dwords that are different to video display memory.

Of course this adds a little overhead to your drawing functions (as they need to update the "line changed" flags), and the extra work involved in copying the data from the buffer to display memory (and the extra RAM accesses) makes it look like it'd be a lot slower; but in practice video display memory is so slow (compared to CPU and RAM speeds) that this can make a significant performance improvement (by avoiding as many writes to display memory as possible).


Cheers,

Brendan

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 7:47 am
by Combuster
StephanVanSchaik wrote:I think Bresenham's books and resources might be a good recommendation as well, that is, if you can get your hands on them.
You might want to start with this explanation

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 10:34 am
by DavidBG
Brendan wrote:I assume your using something like "putpixel(x, y, colour)", where every time you call putpixel it calculates the address of the pixel in display memory? That's insanely bad. You should only calculate the position of the starting pixel, and then update this address for each pixel you draw.
Right on, Brendan, that's exactly what I'm doing (I'll be sure to change that). I do know how to implement the Bresenham line algorithm, I just haven't done it yet, as I didn't yet need it.

All that code you posted Brendan, should be very helpful to a lot of people. Thanks.

David

EDIT:
Brendan wrote:Mostly, you should get acceptable results on Bochs (which is much slower than real hardware) in all video modes without any hardware acceleration; and if you don't then your code needs to be optimised more...
I get around 32 frames per second in 640x480x24 screen resolution in MS Virtual PC (the emulator I use). Emulators are always slower than real hardware, as are code interpreters and virtual machines.

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 7:24 pm
by quanganht
DavidBG wrote:I get around 32 frames per second in 640x480x24 screen resolution in MS Virtual PC (the emulator I use). Emulators are always slower than real hardware, as are code interpreters and virtual machines.
If you have a CPU capable of Intel-VT or AMD-V, then try VMware instead. It is way more better than VirtualPC (personally, I think everything that come from MS is shitty)

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 7:42 pm
by DavidBG
I didn't know VMWare was free.

As to everything MS makes is bad I not quite sure about that, although I must admit I don't like Microsoft's attitude or way of doing things.

To Microsoft, a bug is not a bug it's a feature. That's the worst thing.

I'll check out VMWare.

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 7:49 pm
by DavidBG
I looked at the VMware site but it seems VMware workstation is a trial version, and I don't want to buy a virtual machine at the moment. Correct me if I'm wrong.

Re: Is there any other way to draw other than pixel by pixel?

Posted: Wed Feb 10, 2010 10:21 pm
by Brendan
Hi,
DavidBG wrote:I looked at the VMware site but it seems VMware workstation is a trial version, and I don't want to buy a virtual machine at the moment. Correct me if I'm wrong.
Recent versions of VirtualPC require Intel-VT or AMD-V. VirtualBox will use it if it's present but work without it. Both are free.

I like VirtualPC more than VMware workstation (as VMware workstation seems to be slow to startup). All three emulators are too fast if the host computer's CPU is a modern/fast CPU (e.g. 2 to 3 GHz) and you want to know if your code is "good enough" for an old Pentium. Bochs is much better because it is slower (and because of the inbuilt debugger). Of course I've got all of these (and Qemu) setup.
DavidBG wrote:I get around 32 frames per second in 640x480x24 screen resolution in MS Virtual PC (the emulator I use). Emulators are always slower than real hardware, as are code interpreters and virtual machines.
24-bpp modes take some extra skill to optimise because it's harder to avoid unaligned writes. Mostly you want to write 4 pixels (3 aligned dwords) to display memory at a time. I'd be tempted to use a 32-bpp buffer (so you don't need to mess about with alignment in the routines that draw stuff in the buffer and can re-use the same code for 32-bpp), and then do some bit shifting when copying the buffer to display memory (so that writes to video display memory are still aligned properly).


Cheers,

Brendan

Re: Is there any other way to draw other than pixel by pixel?

Posted: Thu Feb 11, 2010 2:17 am
by quanganht
IMO, WMware is quite good. The VM behaviors seems to be more correct than other emulators. Also it can run with realtime synchronize. About the fee, you can get the lastest WMware Player (currently 3.0) which is totally free, and is able to create virtual machines.