Message-ID: From: Shawn Hargreaves To: djgpp AT delorie DOT com Subject: Re: Accessing BITMAPs Directly in Allegro Date: Tue, 10 Mar 1998 09:37:43 -0000 MIME-Version: 1.0 Content-Type: text/plain Precedence: bulk Colin Walsh writes: > I'm currently trying to eke out as much speed as possible from my 3D > engine, and I figure that the _putpixel/_getpixel routines (even > for asm) should be slower that directly accessing the bytes in the > BITMAP. If you look in allegro.h, you will see that the _putpixel() function is implemented as: void _putpixel(BITMAP *bmp, int x, int y, unsigned char color) { asm ( " movw %w0, %%fs ; " " .byte 0x64 ; " " movb %b3, (%1, %2) " : : "rm" (bmp->seg), "r" (bmp_write_line(bmp, y)), "r" (x), "qi" (color) ); } This is essentially a _farpokeb() call where the destination address is provided by the bmp_write_line() bank switch routine, and is just about the most efficient generic way to do this, but there are a few optimisations that may help in specific situations: - don't bother reloading %fs for each pixel. If you know that you will be drawing onto a memory bitmap you can leave it out altogether and get rid of the ".byte 0x64" selector override, while if you are drawing onto the screen you can just call _farsetsel() once at the start of your drawing loop rather than once per pixel. - if you know that you are drawing onto a memory bitmap or linear framebuffer SVGA screen, get rid of the bmp_write_line() call and lookup the value of bmp->line[y] directly instead. If you might be drawing onto a banked SVGA screen, you can still improve things by only calling the bank switcher once at the start of each scanline rather than once per pixel. > So I was wondering if there is a method of directly accessing the > bitmap, and if so, how? There are many possible ways, and the best one will depend on the exact situation. See the "direct access to video memory" section of the documentation. Vic replied: > You can say bitmap->line[y][x]=color; or color=bitmap->line[y][x] where > y is the Y and x is the X (yes they are reversed!). But this is just > 8 bit modes. I'm afraid for highcolor you need the putpixel routine. That isn't entirely true: you need some casts to convert your pointers to the correct types, but you can still access the memory directly (see allegro.txt somewhere around line 2488). For example the 16 bit version would be: ((short *)bitmap->line[y])[x] = color; For 32 bits: ((long *)bitmap->line[y])[x] = color; For 24 bits (this one is nasty :-) you could either use: bitmap->line[y][x*3] = color&0xFF; bitmap->line[y][x*3+1] = (color>>8)&0xFF; bitmap->line[y][x*3+2] = (color>>16)&0xFF; or perhaps: ((short *)(bitmap->line[y]+x*3)) = color&0xFFFF; bitmap->line[y][x*3+2] = (color>>16)&0xFF; I hope I got those the right way around: be warned that this code is untested :-) Shawn Hargreaves.