Finding a Surface's color in SDL?

Started by
9 comments, last by Jack Sotac 17 years, 8 months ago
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.
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'.
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?
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)
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.
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.
heres a decent gamedev article which mentions one:

http://www.gamedev.net/reference/programming/features/sdl2/page5.asp
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 */    }}
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
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.
Evillive2

This topic is closed to new replies.

Advertisement