Left over garbage pixels from copying a pixel value to new location? C/SDL

Started by
12 comments, last by Servant of the Lord 11 years, 5 months ago

Your drawing a rectangle for the water right then altering the pixels on that rectangle how?

No, I'm creating an empty surface, then altering the pixels on that surface.
I then draw the altered surface onto the screen.

Why are we comparing surfaces?[/quote]
I'm not comparing surfaces, I'm altering one surface (updating it every 1/10th of a second), and drawing it onto the screen (a second surface) every frame.

How are you setting the area of which the pixels values can be gotten and placed elsewhere?[/quote]
I'm not setting the area, I'm passing in the surface to the WritePixel() and ReadPixel() functions. I'm getting and reading pixels from a surface.
Actually, to be more exact, I didn't do any pixel-reading at all, just writing.

In SDL, a "surface" is a image that exists in memory. I'm editing that image; I'm not editing the screen. I'm editing the image, then I'm drawing the image onto the screen.

Quote a line of code, then ask about any specific line of code you have questions about - make sure your specify exactly what part you don't understand.
Advertisement

bump

This isn't an instant chat, and it sometimes takes people a while to respond -- that doesn't mean they aren't going to answer without a "bump". Please wait a minimum of 24 hours before you bump your topics.


Your drawing a rectangle for the water right then altering the pixels on that rectangle how?

Apologies if I'm mistaken, but to me this sounds like you might be a bit confused about exactly how computer graphics work: you don't draw a rectangle and then alter it's pixels, but rather you draw a new rectangle every frame, and by drawing a different rectangle you get the effect of animation. Like a flip book or film.

What specifically don't you understand in SoTL's example?

- Jason Astle-Adams


[quote name='DarkHorseKnight' timestamp='1351938434' post='4996816']
Your drawing a rectangle for the water right then altering the pixels on that rectangle how?

No, I'm creating an empty surface, then altering the pixels on that surface.
I then draw the altered surface onto the screen.

Why are we comparing surfaces?[/quote]
I'm not comparing surfaces, I'm altering one surface (updating it every 1/10th of a second), and drawing it onto the screen (a second surface) every frame.

How are you setting the area of which the pixels values can be gotten and placed elsewhere?[/quote]
I'm not setting the area, I'm passing in the surface to the WritePixel() and ReadPixel() functions. I'm getting and reading pixels from a surface.
Actually, to be more exact, I didn't do any pixel-reading at all, just writing.

In SDL, a "surface" is a image that exists in memory. I'm editing that image; I'm not editing the screen. I'm editing the image, then I'm drawing the image onto the screen.

Quote a line of code, then ask about any specific line of code you have questions about - make sure your specify exactly what part you don't understand.
[/quote]


Okay so return pixels[offset + x]; how does return of pixels[offset + x]; work exactly?


Why are you locking surfaces to access pixels to stop tearing or something?


this function below makes a rect filling it with a user defined color yes?

void DrawRectangle(SDL_Surface *destination, const SDL_Color &color, SDL_Rect *rect = NULL)
{SDL_FillRect(destination, rect, SDL_MapRGB(destination->format, color.r, color.g, color.b));}


this code is fairly hard to grasp the technical concepts

SDL_Surface *CreateEmptySurface(int width, int height, SDL_Surface *surfaceToCompareTo){ SDL_Surface *newSurface = SDL_CreateRGBSurface(surfaceToCompareTo->flags, int width, int height, surfaceToCompareTo->format->BitsPerPixel, surfaceToCompareTo->format->Rmask, surfaceToCompareTo->format->Gmask, surfaceToCompareTo->format->Bmask, surfaceToCompareTo->format->Amask);

if(!newSurface) {std::cerr << "CreateEmptySurface() - Something went wrong creating a " << width << "x" << height << " surface.\n" << " Error: " << SDL_GetError() << std::endl;} //Let's start off filling it with a solid color, like solid white. DrawRectangle(newSurface, SDL_Color(255, 255, 255)); return newSurface;}


What does this do from a technical point of view
SDL_Surface *waterImage = CreateEmptySurface(50, 50, screen);

This code below is oddly written what does that all mean ?
void MakeWaterSurface(SDL_Surface *surface, unsigned int frame){ //We only have 20 frames, so keep within range. frame %= 20; int offset = frame; if(offset >= 10) { //0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 offset = (10 - (offset - 10)); } SDL_Color colors[] = {SDL_Color(100, 150, 190),SDL_Color(100, 160, 180),SDL_Color(100, 170, 170),SDL_Color(100, 180, 160),SDL_Color(100, 190, 150), SDL_Color(100, 190, 170),SDL_Color(100, 190, 190),SDL_Color(100, 190, 210),SDL_Color(100, 190, 230),SDL_Color(100, 220, 250)}; for(int y = 0; y < surface->height; y++) { for(int x = 0; x < surface->height; x++) { //I'm coding blind without a compiler, so I have completely no idea if this will work or not. int waveDepth = ((y + offset) % 10); int waveHorizontalOffset = ((x + (offset/3)) % 20); int waveVerticalOffset = ((x + waveHorizontalOffset) + offset); unsigned colorIndex = (waveDepth + waveVerticalOffset) % 10; WritePixel(x, y, colors[colorIndex], surface); } }}

Theres still more for me to look at but this is as far as I've gotten in trying to understand not used any of this yet.












[/quote]

Okay so return pixels[offset + x]; how does return of pixels[offset + x]; work exactly?

That line was from your code in your original post. smile.png

'pixels' is a pointer to PixelColor types (which is just a typedef of unsigned int). So pixels point to a block of memory it is treating as one or more unsigned ints - in this case, the unsigned ints represent the colors of each pixel on a surface. A surface is just SDL's term for an image in memory.
Using the [] operator let's us pretend pixels is an array (which it basically is - it's a block of memory holding a bunch of unsigned ints). pixels[0] returns the first unsigned int of the pixels in the surface, pixels[1] returns the second, and so on.

However, an image is two-dimensional, and we want to access pixels by an x and a y, not just a single number. So we treat the block of memory like a 2D array, by converting our x and y into an index. The math normally is: index = (y * width) + x;, and we could then go pixels[index].
I explain this more indepth in another thread, with visual aids.

Except that we're multiplying by surface->pitch / sizeof(unsigned int) instead of by width, because SDL surfaces may (to support certain video cards when running in hardware accelerated mode) make the surfaces larger than is actually required. surface->pitch is the real width of the image, including the extra padding. You can read more about this at Sol's SDL tutorials.

Why are you locking surfaces to access pixels to stop tearing or something?[/quote]
I'm not really sure - the SDL documentation says not to access pixels except between locking and unlocking unless the surface doesn't need to be locked. I bet the most important reason for it is that if the surface is hardware accelerated, it'd be stored in Video Card memory, and locking the surface would probably bring it back into RAM for the program to safely work on - but that's speculation.

this function below makes a rect filling it with a user defined color yes?

void DrawRectangle(SDL_Surface *destination, const SDL_Color &color, SDL_Rect *rect = NULL)
{SDL_FillRect(destination, rect, SDL_MapRGB(destination->format, color.r, color.g, color.b));}
[/quote]
It doesn't "make" a rect. It draws a bunch of pixels in the same of a rectangle onto a surface that already exists.
The 'rect' here is just a concept, not a actual thing in memory.
SDL_MapRGB converts a color to the proper color the surface needs, taking into account the surface's format.
'rect' describes the shape of the rectangle to draw, and draws it onto the surface 'destination'. If 'rect' is NULL, the entire surface is filled with the color.

this code is fairly hard to grasp the technical concepts

SDL_Surface *CreateEmptySurface(int width, int height, SDL_Surface *surfaceToCompareTo){ SDL_Surface *newSurface = SDL_CreateRGBSurface(surfaceToCompareTo->flags, int width, int height, surfaceToCompareTo->format->BitsPerPixel, surfaceToCompareTo->format->Rmask, surfaceToCompareTo->format->Gmask, surfaceToCompareTo->format->Bmask, surfaceToCompareTo->format->Amask);

if(!newSurface) {std::cerr << "CreateEmptySurface() - Something went wrong creating a " << width << "x" << height << " surface.\n" << " Error: " << SDL_GetError() << std::endl;} //Let's start off filling it with a solid color, like solid white. DrawRectangle(newSurface, SDL_Color(255, 255, 255)); return newSurface;}
[/quote]
That is a bit confusing, yes. SDL_CreateRGBSurface() creates a new empty surface of size 'width' and 'height', and needs to know the number of bits per pixel, and the different masking formats, for the new surface. We just copy it from a different surface to make sure we get it right - preferably we copy it from the screen, so the screen and the new surface have the same format when drawing (so no conversions need to happen, and the drawing is sped up).
I typo'd it - in the call to SDL_CreateRGBSurface() it should say 'width' and 'height', not 'int width' and 'int height'.

We check to make sure the function didn't return null (which is an error if it does), and since the surface just has random memory junk where its pixels are, we make sure to fill it with the color white.

The entire function just wraps all that for convenience.

What does this do from a technical point of view
SDL_Surface *waterImage = CreateEmptySurface(50, 50, screen);[/quote]
We're calling the function just previously described to create an empty surface of width '50' and height '50', using the same format as 'screen'.

This code below is oddly written what does that all mean ?
void MakeWaterSurface(SDL_Surface *surface, unsigned int frame){ //We only have 20 frames, so keep within range. frame %= 20; int offset = frame; if(offset >= 10) { //0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 offset = (10 - (offset - 10)); } SDL_Color colors[] = {SDL_Color(100, 150, 190),SDL_Color(100, 160, 180),SDL_Color(100, 170, 170),SDL_Color(100, 180, 160),SDL_Color(100, 190, 150), SDL_Color(100, 190, 170),SDL_Color(100, 190, 190),SDL_Color(100, 190, 210),SDL_Color(100, 190, 230),SDL_Color(100, 220, 250)}; for(int y = 0; y < surface->height; y++) { for(int x = 0; x < surface->height; x++) { //I'm coding blind without a compiler, so I have completely no idea if this will work or not. int waveDepth = ((y + offset) % 10); int waveHorizontalOffset = ((x + (offset/3)) % 20); int waveVerticalOffset = ((x + waveHorizontalOffset) + offset); unsigned colorIndex = (waveDepth + waveVerticalOffset) % 10; WritePixel(x, y, colors[colorIndex], surface); } }}[/quote]

That function is weird, yes. Of all the code I posted, that's the bit I'm most iffy about - not being able to compile it (since I don't have SDL on my computer), I don't know for sure if it does what I wanted it to.

It's *supposed to* make a semi-gradiented bands of color, and offset them vertically and horizontally, to sort-of look like waves of water. Whether it works or not, I don't know - which is embarrassing, since I wrote it. rolleyes.gif

This topic is closed to new replies.

Advertisement