[SDL] single pixel drawing

Atrix Wolfe Atrix2 at cox.net
Mon Jul 15 01:30:01 PDT 2002


Drawing single pixels at a time is inherantly slow and if at all possible it
should be avoided.  That aside im going to try to explain as best as i can
and hopefully itll make sense to you. The fastest way to draw a pixel is to
write to the memory directly.  Each SDL surface has 2 members which you are
going to need to draw a pixel (assuming you know screen height and bits per
pixel which it looks like you do ^.^).  The first one is called pixels
(Surface->pixels), this is a pointer to the location in memory that is the
"Screen" itself which you can draw directly to.  The other member is called
pitch.  On screen, pixels look like theyd be stored in a 2 dimensional
array, but in fact it is one long chunk of memory (which a 2d array also is
but never mind that hehe).  The pitch of a surface is how many bytes to add
to your current position on the screen to get to the next line down.  For
example, in 800x600 mode in 16 bit color (assuming no padding between lines)
the screen would be one long chunk of memory that was 960,000 bytes long(800
width *600 height *2 bytes per pixel).  so the first pixel would be at byte
0, and the second pixel would be at byte 2 and the third would be at byte 4
and so on until you got to the 801st pixel which would be at byte 1602.  The
801st pixel also happens to be the pixel defined in 2d coordinates as (0,1)
which is 1 pixel down (:  you with me so far? if we wanted pixel (0,2) we
add 1600 (800 pixels wide * 2 bytes per pixel) and get 3201...so see we add
1600 to a pixel to mode down 1 row.  In this scenario, the pitxh of the
surface is 1600 since you add 1600 to a pixel to get to the one below it.
Sometimes in certain video modes (especialy windowed video modes), the pitch
of the screen is more than youd think it should be because for some reason,
they pad each row of pixels with extra bytes (i think it has something to do
with aligning bytes for optomized memory access but im not 100% sure).  That
means that if your in 800x600 mode in 16 bit color, the picth of the screen
might not be 1600, it could be 1601 or 2050 or even 5000!  Luckily for us we
dont need to know the exact number because sdl tells us what the pitch of a
surface is so we have that part covered.  To get the location of any pixel
on the screen, if we want to draw to pixel (x,y), we use the formula
"location=(y*pitch)+x".  With that in mind, heres a small function to draw a
pixel:

void DrawPixel(SDL_Surface *Surface, int x, int y,Uint16 Color)
{
  Uint16 *Pixel;
  Pixel = (Uint16 *)Surface->pixels + y*Surface->pitch/2 + x;
  *Pixel = color;
}

as you can see we add to Surface->pixels (the begining of the screen) the
following: y*Surface->pitch/2 +x.  As you can see its different than the
above equation because it has a pitch/2.  Thats because the pitch is given
in bytes and our pointer is moving in 2 byte increments (as we are in 16 bit
color mode).   Ok, enough with the technical info.  Basicly if you want to
draw single pixels to the screen, try not to draw them one by one using a
generic pixel drawing function.  If you can...copy/paste the last 2 lines of
code above into the place (or places) where you want to draw your dots, this
should give it a pretty good boost.  The problem with calling generic pixel
drawing functions is that each time you draw the pixel, the CPU pushes all
the variables you pass as arguments onto the stack, then it pushes the
location your program is at then transfers control to the drawing function,
it then takes up a little more stack space for the local pointer (Uint16
*Pixel) and then does the math, moves your color into memory and then pops
all the variables off the stack and returns control to the program where it
was before it tried to draw the pixel.  That sounds like a lot of work
doesnt it?? If instead of a function, you had that pixel code directly
inside a for loop, what would happen instead is it would skip all the steps
up to doing the math, then it would move your color into memory and its
done.  Lots less work isnt it?  I know if you had to do it out by hand youd
want to do as little work as possible, and so do our CPU's, they just live
in much faster time slices than we do and cant complain about it (;

Well, i hope this has helped some.  Good luck with your coding Chris.

-Atrix

----- Original Message -----
From: "Chris Thielen" <chris at luethy.net>
To: <sdl at libsdl.org>
Sent: Sunday, July 14, 2002 6:32 PM
Subject: [SDL] single pixel drawing


> What's the best way to color a single pixel? I tried putpixel() but as
> I've heard from a lot of people now, it's slow and shouldn't be used. I
> draw about 100 pixels to an 800x600 display per frame in 16 bpp. What's
> the best way to draw a single pixel? Should I just use SDL_FillRect?
> (I'm basically looking for the fastest way to draw a pixel, as an
> alternative to putpixel.) Thanks.
>
> -- chris (chris at luethy.net)
>
>
> _______________________________________________
> SDL mailing list
> SDL at libsdl.org
> http://www.libsdl.org/mailman/listinfo/sdl





More information about the SDL mailing list