• Advertisement
Sign in to follow this  

Finding a Surface's color in SDL?

This topic is 4203 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all, first post of many, I hope. :) So, I'm working on an animation class in SDL, and I've got just about everything in place, save one thing. (skip to bottom if you want to avoid the explanation) My animations work by taking an images and cuttting it into "frames". This is accomplished by taking an SDL_Rect and setting it's width and height to the "frame"'s height and width, and the X offset to start of each frame. This works great, except when it reaches the end. I set a variable( the aptly named Last_Frame) to be the last frame, and when curent frame number is equal to Last_Frame, the animation stops, or repeats, depending. But here's the thing, everytime I create a new instance of Animation, I have to set the number of frames. This gets problematic, especially when working with sprites, where there are multiple animations, sometimes of different lengths. Here's the important part, I want to check the surface to see if the current clip(my animation "frame") is blank, but I don't know how. I geuss I would have to find a way to check the color of all the pixels in the "frame" but I don't know how. Also, I'm not exactly sure how SDL handles keyed surfaces, if the key color is removed when blitted, or when loaded. If the latter is the case, then I don't know what color to check for. If the former, it'd prolly be simple, no? Either way, I'm not sure what to do, so any help would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement
do you have one main surface per animation, or is there a surface containing multiple animations? If so, is there one animation per line?

One possible solution would to have an 'empty colour'. This would be used to fill in any empty frame spaces in your surface. Checking to see if a frame is blank would be a simple check to see if the first pixel in that frame matches the 'empty colour'.

Share this post


Link to post
Share on other sites
That's kinda what I have with the key color, lemme show you.

Here's a good(albeit crudely drawn)example:




As you can see, therea re only 4 frames of animation, but room for 6-7;

The pink in the background is removed by SDL, either when blitted, or when loaded, I'm not sure.


So, what you're suggesting is to make the "extra" frames a different color altogether, and when I find that color, to end the animation? My only hesitation is that I'd have two non-displayable colors, the color that's keyed, and the "blank" color, but I think it's worth a shot

So, how would I check for an individual pixel like that?

Share this post


Link to post
Share on other sites
Also, to answer you other question, there's two classes.
One has a single animation, the other has multiple, with one one each line(animations in rows, frames in columns)

Share this post


Link to post
Share on other sites
for surfaces that consist of a single animation, you could work out the number of frames based on the width of the surface.

Use the GetPixel(x,y) method to obtain the colour of a specific pixel.

Yeah you would need to have two non-displayable colours, but it should be a bit simpler than doing GetPixel() on every pixel in the frame to check that they're all blank.

Share this post


Link to post
Share on other sites
Know where I can find a GetPixel function? I don't think SDL has one, unless there is another library for it.

I googled it, but the one I found just crashes my program.

Share this post


Link to post
Share on other sites
heres a decent gamedev article which mentions one:

http://www.gamedev.net/reference/programming/features/sdl2/page5.asp

Share this post


Link to post
Share on other sites
Quote:

Know where I can find a GetPixel function? I don't think SDL has one, unless there is another library for it.

I googled it, but the one I found just crashes my program.


I don't know if this is the one you found or not; I've copied it from the SDL
documentation.


/*
* Return the pixel value at (x, y)
* NOTE: The surface must be locked before calling this!
*/
Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
return *p;

case 2:
return *(Uint16 *)p;

case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;

case 4:
return *(Uint32 *)p;

default:
return 0; /* shouldn't happen, but avoids warnings */
}
}

Share this post


Link to post
Share on other sites
Quote:
Also, I'm not exactly sure how SDL handles keyed surfaces, if the key color is removed when blitted, or when loaded.

SDL_SetColorKey sets a value in the surface to the color specified, which is used during blitting to alpha out transparent pixels. It doesn't modify the actual pixel data. SDL_SetAlpha works the same way, albeit it modifies the 'alpha' variable instead of the 'colorkey' one.

In any case, I think you're going about this the wrong way. It seems like you're trying to embed animation information into a image file - which, I mean, it can be done. Its just kind of icky if you ask me.

A better way would be to create a simple textual format from which you can load animations, ie -

// myanimation.txt
image="ani1.bmp"
playspeed=1000
framecount=3
framerect1={0,0,32,32}
framerect2={32,0,32,32}
framerect3={64,0,32,32}


Or whatever. My example isn't very clean; you could design something a little more robust to suit your needs (heck, you could even use XML :O).

In any case, the benefit to this is that it's, essentially, a script. Your program can dynamically load it in and do the stuff you want it to without requiring a rebuild. And its textual, so it would be a lot easier than encoding the same data into an image.

:3

Share this post


Link to post
Share on other sites
Quote:
In any case, I think you're going about this the wrong way. It seems like you're trying to embed animation information into a image file - which, I mean, it can be done. Its just kind of icky if you ask me.


Actually at image creation time it may be easier to embed pixel markers as opposed to reading text files or generating them for that matter. Since frame sizes can differ between frames (like glyphs in a font) it may be beneficial to "frame" each animation frame with a neutral color(pure green?) and embedded in that frame are different pixels to determine the width, height and anchor point of the sprite it contains. "Isometric Game Programming with DirectX 7" by TANSTAAFL had a whole section on doing this sort of thing in it that I found fascinating although ultimately I don't do my own art so I never got into it very much past the example.

Many bitmap font libraries use this approach to embed glyph information into the actual bitmap instead of creating a new file format etc. Sfont is probably the most well known of these.

Share this post


Link to post
Share on other sites
Quote:
Original post by NinjaMonkeyPirate
Know where I can find a GetPixel function? I don't think SDL has one, unless there is another library for it.

I googled it, but the one I found just crashes my program.

You might need to lock the surface(SDL_LockSurface) before using get/putpixel routines. Also note that no checks on done on the x/y coordinate to make sure they're valid. The caller will have to make sure they are always valid.

Good Luck.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement