Sprites, and good ways to implement them.

Started by
19 comments, last by MrLeap 18 years, 10 months ago
i'm making a tile based (thanks david :P) over head RPG, and as such utilizing sprites is a goal of mine. What would be a good way to do it? The idea for animated sprites that *I* had was to just have a series of conditions that switch textures over a polygon. Psuedo code: while (keys[VK_W]) { loop: texture = walking1.bmp wait 0.3 seconds texture = walking2.bmp } that sort of thing. My way seems REALLY nasty though, so I would assume that the guru's of openGL have devised a much more clever way of doing this, and maybe even wrote a tutorial about it :) If no easier way is known. Can someone point me in the direction of a.. function that acts as a wait? Or even a variable that stores the system clock, so I could do something like.. a = systemclock do until a = a + 0.3 type of things. EDIT: Oh I almost forgot! I'd like figure out how I could make a part of a texture transparent. I think it's called "blitting" or something. Nehe's tutorial just seemed to make an entire texture transparent. a sprite wouldn't be very good if it was just a character within a white box ;)
Advertisement
blitting is the act of copying a bitmap to another bitmap. Colorkeying is when you specify a color to be transparent. Alpha an additional color component that indicates a pixel's opacity, for example, RGBA, which stands for Red, Green, Blue, Alpha.
Thank you SMR, for getting my terminology straight :P

I'm going to go google colorkeying now *laugh*
does anyone know how to do this "colorkeying" shinanigans with bmp's? or do I have to use tga's.
There are no special considerations to make when you create your bitmap. All you need to do is dedicate one specific color to use as the transparent color. I usually use RGB (255, 0, 255). After you create the surface, use the SDL_SetColorKey function to tell SDL that FF00FF should be transparent.
Hi again MrLeap :D
One way that I handle color-keyed bitmaps is by using a simple function that loads up an RGB bitmap like normal, and then I create a pointer to a memory block that can hold data for all the normal pixels, plus an extra channel for the alpha value.

So if you have a pointer to your loaded bitmap:
AUX_RGBImageRec *pRGB = auxDIBImageLoad(filename);


Then you know its size:
int rgb_size = pRGB->sizeX * pRGB->sizeY * 3;


Notice that you're going to be taking the width times the height and multiplying by 3 (three channels). That is the size of your regular bmp image.

You then want to create a pointer to a memory block that has room for 4 channels (RGBA). You can take the width and height and multiply it by 4 this time.

int rgba_size = pRGB->sizeX * pRGB->sizeY * 4;// and this is your new RGBA imageunsigned char *pRGBA = new unsigned char[rgba_size];


Then you basically want to go and loop through the image data, copying over pixels to the RGBA image. You can either pass in a color key value to this loading function, or just hard-code it in this function. So you will go through testing if a pixel in the regular RGB image has the same components as your color key pixel. Here is actual code that I've used:

void LoadTextureColorKey(const char *filename, unsigned char key[], unsigned int& id){	AUX_RGBImageRec *pRGB = auxDIBImageLoad(filename);	if(!pRGB)	{		log("LoadTextureColorKey() :: failed to load texture: %s", filename);		return;	}	unsigned char *pRGBA = NULL;	int rgb_size = pRGB->sizeX * pRGB->sizeY * 3;	int rgba_size = pRGB->sizeX * pRGB->sizeY * 4;	pRGBA = new unsigned char[rgba_size];	int i = 0;	int j = 0;	for(i, j; i < rgb_size; i += 3, j += 4)	{		if(pRGB->data == key[0] &&			pRGB->data[i+1] == key[1] &&			pRGB->data[i+2] == key[2])		{			pRGBA[j+3] = 0;	// transparent		}		else			pRGBA[j+3] = 255;	// opaque				pRGBA[j] = pRGB->data;		pRGBA[j+1] = pRGB->data[i+1];		pRGBA[j+2] = pRGB->data[i+2];	}	glGenTextures(1, &id);	glBindTexture(GL_TEXTURE_2D, id);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexImage2D(GL_TEXTURE_2D, 0, 4, pRGB->sizeX, pRGB->sizeY, 0, GL_RGBA, 				GL_UNSIGNED_BYTE, pRGBA);	/*	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);	gluBuild2DMipmaps(GL_TEXTURE_2D, pRGB->channels, pRGB->sizeX, pRGB->sizeY, GL_RGBA, 						GL_UNSIGNED_BYTE, pRGBA);	*/	if(pRGB)	{		if(pRGB->data)			free(pRGB->data);		free(pRGB);	}	if(pRGBA)		delete[] pRGBA;}


Happy coding :D

-DavidR-



In this world gone mad, we won't spank the monkey; the monkey will spank us.
Do not, if possible, make multiple textures (bitmaps) but just a single one and store texturecoordinates per frame. This way you do not have to switch textures.

Cheers
David wins again! :P Thanks again for holding my hand through this "game making" thing, you're.. most definately going in the readme *laugh*.

Lets see if I can implement your function without bumfungling this up!

by the way: where does the log(); function come from? it looks to me like it's just error reporting, so I commented it out, as it wasn't. uhh.. identified before that. :)
Haha yeah... I wrote a logging function that writes information out to a file so I know what goes on in my program and what not.

-DavidR-
In this world gone mad, we won't spank the monkey; the monkey will spank us.
Note to you: I'm learning C++ and openGL symultanously, and I'm using openGL to kind of give tangible results to all my C++ work, and as such, the following questions I have should sound less stupid than they would otherwise, as you now understand that my expirience with C++ is refering to present and not past expirience ;)

----------

Okay, onward!

Trying to figure out how to call your function, and I'm uhh, going over its workings at the moment, but I have some questions.

LoadTextureColorKey(const char *filename, unsigned char key[], unsigned int& id)

i'm going to go over each of the arguements, tell me if i'm doing something wrong :P

const char *filename
I'll bet this is supposed to be a pointer to the filename of the texture :) But how do I call it? Do I put the file name? preserve the path? put the extention? keep the little pointer-y asterick thing?

unsigned char key[]
I'm confident that this array is the 3 values for the colorkey that I want to be transparent. Only problem is, I can't for the life of me figure out how to use an array as an arguement to a function! if I do key[255,0,255] it says that key is an undefined identifyer, which is absurd, because to ME it seems like i'm identifying it as the arguement to the function :P.

unsigned int& id
I'm going to guess that this is the place in the texture array that my texture is stored. It seems kind of redundant having an arguement for the file name, AND the place in the array where it is for some reason, so I could be wrong.

Again, thank you for walking me through this, and holding my hand. *laugh* You're going in the readme... twice.


This topic is closed to new replies.

Advertisement