Jump to content

  • Log In with Google      Sign In   
  • Create Account


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 DarkHorseKnight   Members   -  Reputation: 143

Like
0Likes
Like

Posted 31 October 2012 - 06:48 PM

Hi all I'm able to draw pixels in many ways and get pixel values and place them somewhere on the screen surface but when It happens the left over pixel is still there and I was hoping someone could show me code and explain how to remove it from the screen surface here is my code to draw and to get pixels :

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <math.h>
#undef main
int y = 10;
int x = 10;
int x2 = 40;
int y2 = 40;
SDL_Surface *Screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE),
*Image;
void pixeldraw(int x, int y , int color)
{
  unsigned int *ptr = static_cast <unsigned int *> (Screen->pixels);
  int offset = y * (Screen->pitch / sizeof(unsigned int));
  ptr[offset + x] = color;
}

unsigned int pixelget(int x, int y)
    {
  unsigned int *ptr = static_cast <unsigned int *> (Screen->pixels);
  int offset = y * (Screen->pitch / sizeof(unsigned int));
  return ptr[offset + x];
    }

int main(int argc , char *argv[])
{

SDL_WM_SetCaption("Image Pixel Manipulation", "PM");

Image = IMG_Load("image.png");


//unsigned int *src0 = (unsigned int *) Image->pixels + y * //Image->pitch;


SDL_FillRect(Screen,NULL,(0,0,0));

pixeldraw(10, 10, 0x0000FF);
   
 
unsigned int color = pixelget(10, 10);
   
pixeldraw(x2,y2, color);
	  
printf("%08x\n", color);

 
    //unsigned int *pixels = (unsigned int*) Screen->pixels;
	  
	   //unsigned int color = pixels[y * (Screen->pitch / /sizeof(unsigned int)) + x];
	  
	   // pixels[y2 * (Screen->pitch / sizeof(unsigned int) + x2] = color;

//src0[1] = 0;

bool done = false;

SDL_Event event;

while(!done)
{
  //SDL_BlitSurface(Image,NULL,Screen,NULL);

  while(SDL_PollEvent(&event))
  {
 
    switch(event.type)
    {
   
	  case SDL_QUIT:
	  return 0;
	  break;
   
    }
 
  }
 
  SDL_Flip(Screen);
}

return 0;
}





any tips and suggestions are also welcome although this was intended as a test case not a perfect example of coding grammatically and correctly per-say of my ability.

Thanks for anyone who reads this :D.

Sponsor:

#2 Servant of the Lord   Crossbones+   -  Reputation: 18462

Like
1Likes
Like

Posted 31 October 2012 - 08:14 PM

You aren't removing a pixel with 'pixelget()', you are only reading a value.

You never "removed" the pixel from the first location, you just asked what color it was.
People never actually are able to "erase" anything (what would that look like? A hole in your window? Posted Image), we just set it to a new color (I explain it more in this thread).

pixeldraw() sets the color value of a pixel that already exists. The pixel already exists, you're just setting its value.
pixelget() copies and returns the color value of a pixel that already exists, but doesn't set the already-existing pixel to anything new.

Does that help explain it?
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#3 DarkHorseKnight   Members   -  Reputation: 143

Like
0Likes
Like

Posted 01 November 2012 - 06:51 AM

Servant the lord : I know I have to redraw over it but how can I detect the pixels around the area of the garbage pixel automatically?

I don't know the code to do it.

#4 DarkHorseKnight   Members   -  Reputation: 143

Like
0Likes
Like

Posted 01 November 2012 - 12:02 PM

Anyone? :(

#5 DarkHorseKnight   Members   -  Reputation: 143

Like
0Likes
Like

Posted 01 November 2012 - 06:51 PM

BUMP

#6 Servant of the Lord   Crossbones+   -  Reputation: 18462

Like
0Likes
Like

Posted 01 November 2012 - 07:26 PM

It takes time to respond (it's only slightly less than 24 hours since my last post) - you don't need to bump so soon (and certainly not twice). Posted Image

I'm not sure what you mean by "detect", and by "garbage pixel". Since I don't quite understand what you are wanting (sorry!), I'm going to ask some questions. Please be as specific and detailed as possible, so I can understand fully, so I can help you.

1) What type of pixels are you looking to "detect"? Are they a certain color?

2) What type of pixels do you consider "garbage"? What makes them "garbage" - their color or some action?

3) You said detect "around" the area of the garbage pixel. What does "around" mean? One pixel around? Two pixels around?

4A) Could you also explain, carefully (it takes me some time to understand Posted Image), what it is, in detail, that you are wanting (and why)?
4B) How are you currently attempting it?

5A) What is the correct result that you'd like?
5B) What is the wrong result your current attempt is giving you?

I'm extremely happy to help (really!) but I need more info, 'cause I'm not quite understanding what you want. Posted Image
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#7 DarkHorseKnight   Members   -  Reputation: 143

Like
0Likes
Like

Posted 02 November 2012 - 06:12 PM

1) What type of pixels are you looking to "detect"? Are they a certain color?

Image pixels as in the pixels in the PNG Image which is RGBA 32bpp "That could be wrong format".

2) What type of pixels do you consider "garbage"? What makes them "garbage" - their color or some action?

There garbage if a pixel value and location is left-over after one pixel value is gotten and placed in a different location.

3) You said detect "around" the area of the garbage pixel. What does "around" mean? One pixel around? Two pixels around?

Detect the pixels around the area as in any area I specify could be 40 by 40 pixels or 100 by 100 pixels.

4A) Could you also explain, carefully (it takes me some time to understand ), what it is, in detail, that you are wanting (and why)?

To make a wave effect by moving 40 by 40 pixels up and down in a png image.

So I can have a decent and cool water effect without loading in each frame of animation of a Adobe After Effects Water Animation .

4B) How are you currently attempting it?

I don't actually know the code to get rid of pixel in a png image which has already been found from pixelget which puts in a different location with the pixel found by the function pixelget.

5A) What is the correct result that you'd like?

1.) having user-defined way to put in the x and y values of the area of pixels

2.) to find and place the pixels in a different location using the x and y values.

5B) What is the wrong result your current attempt is giving you?

Well I can get values and place them somewhere else but not automatically and in a area specified by me in the x and y .

Edited by DarkHorseKnight, 02 November 2012 - 06:13 PM.


#8 Servant of the Lord   Crossbones+   -  Reputation: 18462

Like
1Likes
Like

Posted 02 November 2012 - 09:40 PM

Okay, I think I sortof understand, though I still have some confusion.
Have you checked out Sol's SDL tutorials?

In any case, let's establish some points first.
  • When drawing anything to the screen, it is permanently "there" until you draw something over it.
  • There is no such thing as "erasing" pixels. You can only draw over pixels with a different color.
  • Every frame you should re-draw everything currently on-screen - it's the easiest way to do computer graphics.


Also, your previous code was doing alot of things wrong, now that I look over it a second time.
Here's a list of serious errors:
  • You never freed your resources.
  • You initialized Screen at a global scope.
  • You never called SDL_Init.
  • You never called SDL_Quit.
  • You #undef main, apparently deciding SDL didn't know what it was doing. Posted Image
That's the really bad stuff that could potentially break your program without you knowing why. There's also several bad practices (tons of global variables, for example), but those aren't actual errors like the list above.


 

So, let's do a bit of code. First, our pixel putting and pixel getting functions shouldn't assume we are reading or writing pixels from the screen - we want to be able to read and write to any SDL_Surface (also, we don't want global variables, so the read and write pixel functions shouldn't know about the screen surface anyway).

My SDL is a bit rusty, but (editing your original code) this should work:
typedef unsigned int PixelColor;
void WritePixel(unsigned int x, unsigned int y, PixelColor color, SDL_Surface *surface)
{
	PixelColor *pixels = static_cast<PixelColor*>(surface->pixels);
	int offset = y * (surface->pitch / sizeof(unsigned int));
	pixels[offset + x] = color;
}
unsigned int ReadPixel(unsigned int x, unsigned int y, SDL_Surface *surface)
{
	PixelColor *pixels = static_cast<PixelColor*>(surface->pixels);
	int offset = y * (surface->pitch / sizeof(unsigned int));
	return pixels[offset + x];
}
//Make sure you lock surfaces before editing their pixels.
void LockSurface(SDL_Surface *surface)
{
	if(SDL_MUSTLOCK(surface))
	{
		SDL_LockSurface(surface);
	}
}
//Make sure you unlock surfaces once you are done editing their pixels.
void UnlockSurface(SDL_Surface *surface)
{
	if(SDL_MUSTLOCK(surface))
	{
		SDL_UnlockSurface(surface);
	}
}

I actually don't have SDL on my computer, and so I can't test anything I'm writing here. You might need to tweak some of the code to get it to work.

We'll also want these, for convenience and code clarity:
//Stolen from Lazy Foo's SDL tutorial.
//See here: http://lazyfoo.net/SDL_tutorials/lesson03/windows/devcpp/index.php
//And here: http://lazyfoo.net/SDL_tutorials/lesson05/index.php
SDL_Surface *LoadSurface(const std::string &filepath, const SDL_Color &color = SDL_Color(0, 255, 255))
{
	//The optimized image that will be used
	SDL_Surface* optimizedImage = NULL;
  
	//Load the image using SDL_image
	SDL_Surface* loadedImage = IMG_Load( filename.c_str() );
  
	//If the image loaded
	if( loadedImage != NULL )
	{
		//Create an optimized image
		optimizedImage = SDL_DisplayFormat( loadedImage );
	  
		//Free the old image
		SDL_FreeSurface( loadedImage );
	  
		//If the image was optimized just fine
		if( optimizedImage != NULL )
		{
			//Map the color key
			Uint32 colorkey = SDL_MapRGB(optimizedImage->format, color.r, color.g, color.b);
		  
			//Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent
			SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
		}
	}
  
	//Check if everything went fine.
	if(optimizedImage == NULL)
	{
		//Report an error.
		std::cerr << "LoadSurface() - Something went wrong loading '" << filepath << "'.\n"
				  << "	Error: " << SDL_GetError() << std::endl;
	}
  
	//Return the optimized image
	return optimizedImage;
}
//Also stolen from Lazy Foo's SDL tutorial.
//See here: http://lazyfoo.net/SDL_tutorials/lesson02/index.php
void DrawSurface(int x, int y, SDL_Surface *source, SDL_Surface *destination)
{
	//Make a temporary rectangle to hold the offsets
	SDL_Rect offset;
  
	//Give the offsets to the rectangle
	offset.x = x;
	offset.y = y;
  
	//Blit the surface
	SDL_BlitSurface( source, NULL, destination, &offset);
}

They are slightly modified versions of the functions found at Lazy Foo's SDL tutorials; a set of tutorials you should go.

These two functions we'll also find useful:
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));
}
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;
}

 

Here's what your code should actually look like, if done properly:
int main(int argc, char *argv[])
{
	//----------------------------------
	//Start up SDL.
	SDL_Init(SDL_INIT_EVERYTHING);
	//----------------------------------
  
	//----------------------------------
	//Create the window.
	SDL_Surface *screen = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE);
	//----------------------------------
  
	//----------------------------------
	//Load resources.
  
	//Here we are loading an image just to show how.
	//'exampleImage.png' is being looked for in the same folder that the program's executable is in.
	SDL_Surface *exampleImage = LoadSurface("./exampleImage.png");
  
	//----------------------------------
  
	//----------------------------------
	//Main loop:
  
	bool done = false;
  
	//Loop until we are done.
	while(!done)
	{
		//----------------------------------
		//Handle user input.
		while(SDL_PollEvent(&event))
		{
	  
			switch(event.type)
			{
				case SDL_QUIT:
				{
					//Don't do return 0 here, set the 'done' bool to true, so we exit properly and free our resources.
					done = true;
				}
				break;
			}
	  
		}
	  
		//----------------------------------
		//Handle time-based updating.
	  
	  
		//----------------------------------
		//Handle logic/thinking.
	  
	  
		//----------------------------------
		//Draw everything.
		{
			//Reset the screen to all black.
			DrawRectangle(screen);
		  
			//Draw any images.
			DrawSurface(50, 50, exampleImage, screen);
		  
			//Update the screen. Anything drawn this frame now takes effect.
			SDL_Flip(screen);
		}
	  
		//----------------------------------
	  
		//----------------------------------
		//Delay a little, so we don't take 100% CPU usage.
		SDL_Delay(0);
	  
		//----------------------------------
	}
	//----------------------------------
  
	//----------------------------------
	//Free resources. Anything we load _must_ be freed - it's one of the marks of a good programmer.
  
	//Any surfaces we load or create (except for 'screen'!) needs to be freed.
	SDL_FreeSurface(exampleImage);
  
	//----------------------------------
  
	//----------------------------------
	//Shut down SDL.
  
	SDL_Quit(); //SDL_Quit() also frees 'screen' for us, so we don't need to.
  
	//----------------------------------
  
	return 0;
}

 
Moving on to the next portion: Proper timing.
Really, I'll just link to another Lazy Foo tutorial: Frame indpendant movement (lesson 32).

Here's the code I'm adding for time management. I find time is easier to manipulate if it's in a float or double, but that's a matter of preference.
float SecondsSinceLastFrame()
{
	static Uint32 lastFrameTime = 0;
  
	//Get the current time.
	Uint32 currentTime = SDL_GetTicks();
	Uint32 timeDifference = (currentTime - lastFrameTime);
	if(timeDifference > 0)
	{
		//Store the new current time.
		lastFrameTime = currentTime;
	  
		//Convert from millaseconds to seconds, and return as a float.
		return (float(timeDifference) / 1000.0f);
	}
	else
	{
		return 0.0f;
	}
}

 
Now we can manipulate pixels based on time.

I'm going to create a new surface to hold what we are manipulating, rather than drawing on the screen directly.
SDL_Surface *waterImage = CreateEmptySurface(50, 50, screen);

Every 1/10th of a second, I'm going to update the water image with this function:
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);
		}
	}
}

Not the best looking water in the world, I'm just showing you the basics of how it could be done.
I'm assuming it's not the best looking water in the world, anyway, since I can't compile it to see how it looks. Posted Image
Not only that, but I'm also really sleepy and not thinking straight, so double the chance of mistakes. Posted Image

Here's the whole main body again, with the additions:
const int NumWaterFrames = 20;
const int HalfOfWaterFrames = (NumWaterFrames/2);
const int NumColors = 10;
void MakeWaterSurface(SDL_Surface *surface, unsigned int frame)
{
	//We only have 20 frames, so keep within range.
	frame %= NumWaterFrames;
  
	int offset = frame;
	if(offset >= HalfOfWaterFrames)
	{
		//0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
		offset = (HalfOfWaterFrames - (offset - HalfOfWaterFrames));
	}
  
	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) % NumColors);
		  
			int waveHorizontalOffset = ((x + (offset/3)) % NumWaterFrames);
			int waveVerticalOffset = ((x + waveHorizontalOffset) + offset);
		  
			unsigned colorIndex = (waveDepth + waveVerticalOffset) % NumColors;
		  
			WritePixel(x, y, colors[colorIndex], surface);
		}
	}
}
int main(int argc, char *argv[])
{
	//----------------------------------
	//Start up SDL.
	SDL_Init(SDL_INIT_EVERYTHING);
	//----------------------------------
  
	//----------------------------------
	//Create the window.
	SDL_Surface *screen = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE);
	//----------------------------------
  
	//----------------------------------
	//Load resources.
  
	//Here we are loading an image just to show how.
	//'exampleImage.png' is being looked for in the same folder that the program's executable is in.
	SDL_Surface *exampleImage = LoadSurface("./exampleImage.png");
  
	SDL_Surface *waterImage = CreateEmptySurface(40, 40, screen);
  
	//----------------------------------
  
	//----------------------------------
	//Main loop:
  
	bool done = false;
	float accumulatedWaterTime = 0.0f;
	unsigned int currentWaterFrame = 0;
  
	//Loop until we are done.
	while(!done)
	{
		//----------------------------------
		//Handle user input.
		while(SDL_PollEvent(&event))
		{
	  
			switch(event.type)
			{
				case SDL_QUIT:
				{
					//Don't do return 0 here, set the 'done' bool to true, so we exit properly and free our resources.
					done = true;
				}
				break;
			}
	  
		}
	  
		//----------------------------------
		//Handle time-based updating.
	  
		float delta = SecondsSinceLastFrame();
		if(delta > 0.0001f)
		{
		  
			accumulatedWaterTime += delta;
			bool updateSurface = false;
			while(accumulatedWaterTime > 0.1f) //One tenth of a second.
			{
				currentWaterFrame++;
				if(currentWaterFrame >= NumWaterFrames)
				{
					currentWaterFrame %= NumWaterFrames;
				}
			  
				updateSurface = true;
			}
		  
			if(updateSurface)
			{
				MakeWaterSurface(waterImage, currentWaterFrame);
			}
		  
		  
		}
	  
		//----------------------------------
	  
		//----------------------------------
		//Handle logic/thinking.
	  
	  
		//----------------------------------
	  
		//----------------------------------
		//Draw everything.
		{
			//Reset the screen to all black.
			DrawRectangle(screen);
		  
			//Draw any images.
			DrawSurface(50, 50, exampleImage, screen);
		  
			//Update the screen. Anything drawn this frame now takes effect.
			SDL_Flip(screen);
		}
	  
		//----------------------------------
	  
		//----------------------------------
		//Delay a little, so we don't take 100% CPU usage.
		SDL_Delay(10);
	  
		//----------------------------------
	}
	//----------------------------------
  
	//----------------------------------
	//Free resources. Anything we load _must_ be freed - it's one of the marks of a good programmer.
  
	//Any surfaces we load or create (except for 'screen'!) needs to be freed.
	SDL_FreeSurface(exampleImage);
  
	//----------------------------------
  
	//----------------------------------
	//Shut down SDL.
  
	SDL_Quit(); //SDL_Quit() also frees 'screen' for us, so we don't need to.
  
	//----------------------------------
  
	return 0;
}

 
Any questions about any of that? It's alot to chew at once, I'm sure.

I strongly suggest reading Lazy Foo's SDL tutorials, for starters, and following it up with Sol's SDL tutorials.

Edited by Servant of the Lord, 02 November 2012 - 09:45 PM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#9 DarkHorseKnight   Members   -  Reputation: 143

Like
0Likes
Like

Posted 03 November 2012 - 04:27 AM

I generally have no idea about all of this accept my 2 functions , it would be awesome if someone could do like a simplist explanation on all this new stuff so I can see and know whats going on .


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

Why are we comparing surfaces?


How are you setting the area of which the pixels values can be gotten and placed elsewhere?

yes a full explanation is required ! Posted Image

Edited by DarkHorseKnight, 03 November 2012 - 04:28 AM.


#10 DarkHorseKnight   Members   -  Reputation: 143

Like
-2Likes
Like

Posted 03 November 2012 - 07:40 AM

bump

#11 Servant of the Lord   Crossbones+   -  Reputation: 18462

Like
0Likes
Like

Posted 03 November 2012 - 06:42 PM

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?

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?

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.
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#12 jbadams   Senior Staff   -  Reputation: 17921

Like
0Likes
Like

Posted 03 November 2012 - 07:15 PM

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?

#13 DarkHorseKnight   Members   -  Reputation: 143

Like
0Likes
Like

Posted 04 November 2012 - 06:48 AM


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?

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?

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.



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.














#14 Servant of the Lord   Crossbones+   -  Reputation: 18462

Like
0Likes
Like

Posted 04 November 2012 - 12:15 PM

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. Posted Image

'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?

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));}

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;}

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);

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);		  }	   }}


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. Posted Image

Edited by Servant of the Lord, 04 November 2012 - 12:15 PM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS