Archived

This topic is now archived and is closed to further replies.

2D Sprite Textures... Larger Sets

This topic is 5125 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

Hey, I''m looking for a kind of "generic" solution here, so it doesn''t really matter what API you''re working with here. I''ve got a character and all movements mapped out in a single image. By simply moving the texture co-ordinates, you effectively get a tileset for animation. However, what can be done when this image is greater than 256 x 256? I know I shouldn''t load a texture larger than that, because some of the older cards can''t handle that. And even then, what if my character''s "animation page" goes beyond 512 x 512 or even larger? What kind of solutions can be done for something like this? I thought of maybe making each animation its own "animation page" and then you load up an array of textures which each row in the array being an animation (ie, walk = 0, run = 1, jump = 2) and then you advance the frame right or left by moving the texture co-ordinates. Not too sure if thats really a viable solution or not. So how do you other 2D guys do it?

Share this post


Link to post
Share on other sites
Here's my animation class:


class Animation {
public:
int Type; // 0 = plays anim once, 1 = loops, 2 = rythmic (loops from 0 to 5 and then back from 5 to 0, and so on)


string TextureLocation;
float FrameDelay; // delay between frames in seconds

bool Direction; // TRUE = forward, FALSE = backwards (used in the DisplayAnim function)

float CTime; // used to display the anim

float LTime; // same

int CurrentFrame; // current frame for the display anim function

UINT texture[1]; // for texture loader

float Width;
float Height;
int Frames; // number of frames

float FrameWidth; // 1 divided by the number of frames (for the texture coords)

float RotAngle; // angle of the animation

Vector2 Pos; // and it's position

int Layer; // and layer, -1, 0, 1, 2 etc


Animation();
void ReadData(); // reads data from text file

void DisplayAnim(); // displays the animation

int CreateTexture();
};


Basically I read all the necessary data from a text file and my game automatically displays the animation according to it's parameters. The resolution of the animation has absolutely no relation to 2D animations to be honest; I'm not quite following your question there. You're working only with variables in the display animation function, here's my display animation function:



void Animation::DisplayAnim()
{
glPushMatrix();
glRotatef(RotAngle,0.0f,0.0f,1.0f);
glBindTexture(GL_TEXTURE_2D, g_texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(CurrentFrame * FrameWidth, 1.0f); glVertex3f(Pos.x - Width/2, Pos.y + Height/2, Layer);
glTexCoord2f(CurrentFrame * FrameWidth + FrameWidth, 1.0f); glVertex3f(Pos.x + Width/2, Pos.y + Height/2, Layer);
glTexCoord2f(CurrentFrame * FrameWidth + FrameWidth, 0.0f); glVertex3f(Pos.x + Width/2, Pos.y - Height/2, Layer);
glTexCoord2f(CurrentFrame * FrameWidth, 0.0f); glVertex3f(Pos.x - Width/2, Pos.y - Height/2, Layer);
glEnd();
glPopMatrix();

CTime = timeGetTime () * 0.001f;

if(CTime - LTime > FrameDelay)
{
LTime = CTime;

switch(Type)
{
case 0: if (CurrentFrame < Frames - 1) CurrentFrame++; // Type 0 plays anim once

break;
case 1: if (CurrentFrame < Frames) CurrentFrame++; if (CurrentFrame == Frames) CurrentFrame = 0; // Type 1 loops

break;
case 2: if (CurrentFrame == 0) Direction = TRUE; // Type 2 loops from 0 to 5 and then from 5 to 0

if (CurrentFrame == Frames - 1) Direction = FALSE;
if (Direction)
CurrentFrame++;
else
CurrentFrame--;
break;
}
} // end of if

}


Source tags messed up some of the spacing but it's still readable. It's really self explanatory to be honest, mainly look at the glTexCoords paramters... It's done in OpenGL, so about other APIs I really can't help ya there sorry.

[edited by - Enokh on November 28, 2003 7:55:51 PM]

Share this post


Link to post
Share on other sites
Hey, I can dig it just like you have it. But what do you do for a texture for your animation thats bigger then 256 x 256?

Like say, Crono''s Animation Set from Chrono Trigger here:
http://tsgk.captainn.net/sprites_snes_chronotrigger_maincharacters-crono.html

Its way bigger then 256 x 256, but I thought if you loaded something like that into memory you''d A) take up quite a bit of space and B) some video cards can''t handle greater then 256 x 256 textures.

Maybe I''ve been mislead?

Share this post


Link to post
Share on other sites
quote:
Like say, Crono''s Animation Set from Chrono Trigger here:
http://tsgk.captainn.net/sprites_snes_chronotrigger_maincharacters-crono.html

I''m always amazed by how much art goes into video game programming.
quote:
Original post by GroZZleR
Hey, I can dig it just like you have it. But what do you do for a texture for your animation thats bigger then 256 x 256?

Its way bigger then 256 x 256, but I thought if you loaded something like that into memory you''d A) take up quite a bit of space and B) some video cards can''t handle greater then 256 x 256 textures.

Maybe I''ve been mislead?
The 256x256 limit is for certian old cards. If you want to stick with it, you are a better game programmer than me.

If you want to run an animation that goes beyond 256x256, you have to split the animation into two textures, and then specify which texture you''re animating with. IF your character is multiple 256x256 blocks, you might need to tile him.


You array animation works as well, however, make sure you don''t assume you''ll be going sequential when you code. Sometimes you need to skip around during your animations. Sometimes you''re walking, then you get hit with something and fall over, which might be frame 1,2,3,4,1,2,3,4,1,2,3,4,1,2,10,11,12,12,12,...

Sorry, I''m a bit tired.

~~~~~
"dede dude" - bishop_pass
Download and play Slime King I.

Share this post


Link to post
Share on other sites
...I think he means to ask how can he animate, say, a 32x32 pixel tile with tiles from an image file > 256x256 (not above this). In which case, he''ll need some tips concerning the use of multiple texture files, and knowing when to bind one over the other.

Share this post


Link to post
Share on other sites
quote:
Original post by wAVaRiaN
...I think he means to ask how can he animate, say, a 32x32 pixel tile with tiles from an image file > 256x256 (not above this). In which case, he''ll need some tips concerning the use of multiple texture files, and knowing when to bind one over the other.


Precisely =)

Share this post


Link to post
Share on other sites
1. Create a file containing meta-data containing the location & size of each sprite in that giant image. When you need a texture, you can find it using your metal data, and load it into a temporary texture. Then simply bind the temporary texture and use it once. This is probably the slowest way of doing it, but its acceptable, expecially if you don''t have enough memory to keep the whole texture.

2. Create a file containing meta-data containing the location & size of each sprite in that giant image. In a preprocessing step, simply break the image into 100s of managable textures and store those textures in an array. Then bind which texture you''d like to use.

3. The way my new engine handles it is by first storing the large texture as 100s of image files. Frame1.bmp, frame2.bmp, etc. Then during pre-processing, I load my images into a series of 512x512 textures, and use a class to figure out what texture is where. So 1 texture may have 4 sprites, for example.

Everytime you bind a new texture, you take a hit, so if I correctly choose which textures are used one after another, I can avoid it. I simply choose only part of the texture to display my sprite. It works better for scenery than characters, since which character animations are used often is a major guess.

The advantage of this, is that if I ever decide to profile my game, I might be able to speed up the animations a bit. If you are lazy, you can always store your textures the way I pre-process them, and then use them that way.

4. Use a texture cache. Each character or level has his or her own texture chache, which is simply a 256x256 bitmap. Everytime you want a new texture, you first look to see if its loaded into its cache. If it is, then you bind that texture, and use that. If it isn''t, then you load the new sprite into the LRU(Least Recently Used) sprite''s place. Loading the sprite is simular to #1, just find it with yoru meta-data, and then replace it and bind the texture.

~~~~~
"dede dude" - bishop_pass
Download and play Slime King I.

Share this post


Link to post
Share on other sites