Best way of manipulating pixels
Jose Rubio

Hi everybody,

I have a project right know where I may have the need to manipulate pixels in a BITMAP and I wonder which is the most efficient way of doing so. I know there are getpixel and putpixel funcions, but I wonder if accessing directly to the BITMAP struct would be a better approach, and also if there are any hints on how doing so as best as possible.

Also, making distinction between A4 and A5 would be great, since I will soon be switching to A5 and would be great to be able to port everything to it.

I suppose that the type of BITMAP (memory, video) will also have an impact...

Any advice on this will be great.

Thanks!

beoran

As described in this thread amongst others: https://www.allegro.cc/forums/thread/614217/0, the fastest way to directly access pixels in Allegro5 is to use al_lock_bitmap(). However, nowadays almost all common platforms have a GPU, pixel per pixel access is not the best way to do graphics. In stead, use al_draw_bitmap() or the primitives extension, this will be translated under the hood into much faster OpenGL or Direct3D calls.

Jose Rubio

I'm aware that nowadays this is kind of retro and not very recommendable, but among other things, I want to impart some lessons about game programming starting by pixel pushing in a framebuffer, as in old DOS days.

Simulating it by writing pixels to a texture would do... it's just that I need to find a nice and clean way to do it, I don't want to choose the worst way.

Arthur Kalliokoski

I've often used glDrawPixels to draw a memory buffer to the screen, it works fairly fast in my experience.

[EDIT]

I last mentioned it here.

Jose Rubio

I'll have to test glDrawPixels(). This may be exactly what I am looking for, since you still have to wortk your way around a framebuffer, and then GL will take care of it and render it on screen.

Elias

The way I like most is to simply use a memory buffer. Something like

char screen[320 * 240 * 3];

void putpixel(void) {
    cursor.screen[cursor.y * 320 * 3 + cursor.x * 3 + 0] = cursor.red;
    cursor.screen[cursor.y * 320 * 3 + cursor.x * 3 + 1] = cursor.green;
    cursor.screen[cursor.y * 320 * 3 + cursor.x * 3 + 2] = cursor.blue;
}

The only time I need Allegro is my call to al_lock/unlock_bitmap which copies it to a bitmap, once per frame - so it's plenty fast.

Jose Rubio

If I am not mistaken, this is the approach taken by some modern ports of Doom, though they almost all use SDL.

By the way, how do you perform a copy to the BITMAP?

Elias
lock = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_BGR_888, ALLEGRO_LOCK_WRITEONLY);
for (int y = 0; y < 240; y++) {
    char *p = lock->data;
    p += y * lock->pitch;
    memcpy(p, screen + y * 320 * 3, 320 * 3);
}
al_unlock_bitmap(bitmap);

Thread #614358. Printed from Allegro.cc