Trying to figure out SDL pixel manipulation?

Hello so I've found code that plots a pixel in an SDL Screen Surface :

void putpixels(int x, int y, int color)
{
unsigned int *ptr = (unsigned int*)Screen->pixels;

int lineoffset = y * (Screen->pitch / 4 );
ptr[lineoffset + x ] = color;

}


But I have no idea what its actually doing here this is my thoughts.

You make an unsigned integer to hold the unsigned int version of pixels then you make another integer to hold the line offset and it equals to multiply by pitch which is then divided by 4 ...

Now why am I dividing it by 4 and what is the pitch and why do I multiply it??

Why must I change the lineoffset and add it to the x value then equal it to colors?

I'm soo confused.. ;/

I found this function here -> http://sol.gfxile.net/gp/ch02.html

• Downvotting and not commenting is bad guys. And I don't see why this question is bad. Commented Oct 3, 2012 at 14:49
• people do it to take the piss its okay I'm used too it stack exchange is known for harsh behavior Commented Oct 3, 2012 at 14:50
• I'm downvoting because this question shows lack of research and is too localized in my opinion. I'm not sure what the other down vote was for. Commented Oct 3, 2012 at 17:14
• @NoobScratcher Including the URL to the page in which the function you are not bothering to do thorough research on is contained hardly counts as research on its own. Especially when the page says "the pitch tells us how long a scanline is. The pitch is always at least as big as the width," yet you specifically ask "what is the pitch and why do I multiply it??". That's why I downvoted. Commented Oct 4, 2012 at 2:26
• I'm downvoting for lack of research too, considering the page explains it and you can do a little background reading on the topic at hand (or if you're completely out of your depth and have no idea what the topic is, you need to take a few steps back). Commented Oct 4, 2012 at 2:37

Next, we're calculating the line offset. We're dividing the pitch by 4; the pitch value is in bytes, but we're moving four bytes at a time.

It should be:

void putpixels(int x, int y, int color)
{
unsigned int *ptr = (unsigned int*)Screen->pixels;

int lineoffset = y * (Screen->pitch / sizeof( unsigned int ) );
ptr[lineoffset + x ] = color;

}


These are all good answers but nobody explained the reason why you need to access the pixels in the way you do. The pixel data is a one dimensional array. For a 10x10 screen, the following is how you can visualize the data being set up.

// This is how it is actually setup
unsigned int data[100];

// This is how people envision it being setup
unsigned int data[10][10] // aka data[x][y]


Since it's a one dimensional array, and you have x,y coordinates you need to translate them to their actual position inside that array.

// This gets the y offset
int lineoffset = y * (Screen->pitch / 4 );

// Now that we know the Y offset, you can add the x position
// to access your specific pixel. Here you're assigning the
// value of a color.
ptr[lineoffset + x ] = color;


If you plot a few pixels on the screen and cout their x, y and then how it's being manipulated you'll see what it's doing and it will be pretty clear. If this WAS a multidimensional array, you could think of the first line as the Y for loop and the second as the X for loop:

for (int x = 0; x < 10; x++) { // = int lineoffset = y * (Screen->pitch / 4 );
for (int y = 0; y < 10; y++) { // ptr[lineoffset + x ]
data[x][y] = color; //  = color;
}
}


Hope this helps :)

This site contains an Introduction to SDL Video. You'll find the information there to properly set pixels.

I also highly recommend you download the official documentation from the SDL website: http://www.libsdl.org/docs.php.

The code on the site you linked to is quite hack-ish, and not very clear.

For one thing, it's hard-coded only to work with specific resolutions at 32 bits-per-pixel color depth. The versions of getpixel() and putpixel() that are in the first link are safer (but don't forget to SDL_LockSurface the screen first, and SDL_UnlockSurface it afterwards).

You don't need to understand every detail of how these functions work in order to use SDL effectively. Basically they're providing you an interface to work directly with the pixels, without needing to worry about the low-level stuff, like memory alignment and bytes-per-pixel, etc.

But maybe you should play a little with SDL_FillRect() and SDL_BlitSurface() to get used to SDL first :)

But, here's some background info that may help interpreting the code:

You probably know that an SDL_Surface holds image data. It can also provide access to the screen. Raw access to pixels can be obtained using SDL_Surface's pixels member, after locking the surface. You can treat pixels as an array of bytes.

One would assume the size of the pixels data array is just the Width * Height * BytesPerPixel, but it's not. It's Pitch * Height. The pitch is the length of one scanline. Why would the length of one line not be Width * BytesPerPixel?

For one thing, scanlines are aligned to a 4-byte boundary for efficiency reasons. Secondly, if you request an irregular resolution for a hardware surface, SDL will give you a different resolution, with the width set to one you requested, but using the pitch of the real video surface.

So you must use pitch when dealing with the raw pixel data.

unsigned int *ptr = (unsigned int*)Screen->pixels; As each pixel have 4 bytes (1 byte for each component RGBA) and also unsigned ints have 4 bytes, it is storing the image data in a unsigned int pointer. So each unsigned int is a pixel of the image.

int lineoffset = y * (Screen->pitch / 4 ); This gets in what line does the pixel lies on. I'm not very sure what pitch is, but probably related to the size of a line. so That pitch / 4 = linesize this gives that y * linesize = firstPixelofTheLine

then it just access the pixel you want with ptr[lineoffset + x ] as it uses the pointer as an array and sets it to color.

Btw, if you don't understand these pixels and surfaces operations. It would be better to you to stick with something more easier, like SFML, XNA or even Gamemaker or unity.