Sign in to follow this  

SDL/OpenGL sprite transparency

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

I'm recently using SDL's OpenGL implementation, and I'm having trouble with setting colour keying. Here's my sprite loading code, I'm using SDL_image:

int load_texture(s_texture_ptr texture,char* filename,Uint8 r,Uint8 g,Uint8 b)
{
	if (!texture)
	{
		printf ("Invalid texture pointer passed while attempting to load %s\n",filename);
		return 0;
	}
	
	SDL_Surface* surf,*newsurf;
	
	surf = IMG_Load(filename);
	
	if (!surf)
	{
		printf ("Unable to load %s\n",filename);
		return 0;
	} //end if

	//now convert to OpenGL
	//do some mathemagic
	SDL_PixelFormat targetfmt;	/*the target format*/

	targetfmt.palette = NULL;
	targetfmt.BitsPerPixel = 32;	/*32 bits per pixel*/
	targetfmt.BytesPerPixel = 4;	/*a whopping four bytes per pixel*/

	targetfmt.Rmask = 0x000000ff;
	targetfmt.Gmask = 0x0000ff00;
	targetfmt.Bmask = 0x00ff0000;
	targetfmt.Amask = 0xff000000;

	newsurf = SDL_ConvertSurface(surf,&targetfmt,SDL_SRCCOLORKEY);

	if (!newsurf)
	{
		printf ("Error converting %s to 32-bit surface\n",filename);
		return 0;
	}

	/*success*/
     SDL_SetColorKey(newsurf,SDL_SRCCOLORKEY,SDL_MapRGB(newsurf->format,r,g,b));

//now we rock
	glGenTextures(1,&texture->texture);
	
	glBindTexture(GL_TEXTURE_2D,texture->texture);
	
	//filtering
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	
	glTexImage2D(GL_TEXTURE_2D,0,4,newsurf->w,newsurf->h,0,GL_RGBA,GL_UNSIGNED_BYTE,newsurf->pixels);

	texture->width = newsurf->w;
	texture->height = newsurf->h;

	SDL_FreeSurface(newsurf);
	SDL_FreeSurface(surf);
	
	printf ("Loading %s successful\n",filename);
	
	return 1;	/*scucess*/
}

The pixel that's (r,g,b) is supposed to have been set to transparent, no? Here's my rendering code
void draw_texture_src(s_texture_ptr texture,int u0,int v0,int u1,int v1,int x,int y)
{
      if (!texture)
            return;     
      
      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
      
      glTranslatef(x,y,1.0f);

      glScalef(u1-u0,v1-v0,1.0f);

      float tu0 = u0/(float)texture->width;
      float tv0 = v0/(float)texture->height;
      float tu1 = u1/(float)texture->width;
      float tv1 = v1/(float)texture->height;
      
      glBindTexture(GL_TEXTURE_2D,texture->texture);

	glBegin(GL_QUADS);
		glTexCoord2f(tu0,tv0);        glVertex2f(0.0f,0.0f);
		glTexCoord2f(tu0,tv1);    	glVertex2f(0.0f,1.0f);
		glTexCoord2f(tu1,tv1);    	glVertex2f(1.0f,1.0f);
		glTexCoord2f(tu1,tv0);	      glVertex2f(1.0f,0.0f);
	
	glEnd();      


}     

And for some reason, no matter what I do (removing SDL_SetColorKey and manually setting the color keyed pixels transparent), it won't render transparent!!! I know for sure that the alpha component of the pixels I don't want are set to 0, but how come it won't render transparent? I've done this before with IPicture, OpenGL seems to automatically set my black pixels to transparent without me even asking it to, but SDL's OpenGL (even though both are technically the same) doesn't do that for me! This is driving me crazy, Cheers, Cipher3D

Share this post


Link to post
Share on other sites
Setting the color key will not affect your alpha at all. From what I understand, that is purely a hardware surface thing. It doesn't even affect the alpha anyways. From my understanding, alpha blending and color keying are two seperate operations.

You are loading TGA's, right? Shouldn't you be able to edit the alpha channel from your image editor? Or, you could manualy change the data yourself.

Set up a loop that tests the rgb value from a source surface and if it matches the value you wanted for the color key, set the alpha to 0, otherwise set the alpha to 1.0, or whatever it is.

Share this post


Link to post
Share on other sites
yup, blending was enabled, i already tried the alternate method, by looping through the pixels and setting alpha to zero:



for (int y=0;y<newsurf->h;y++) {
for (int x=0;x<newsurf->pitch;x+=4) {
loc = x+(y*newsurf->pitch);
if (pix[loc] == r&&pix[loc+1]==g&&pix[loc+2]==b)
pix[loc+3] = 0;
}
}






Doesn't work either

[sad]

Share this post


Link to post
Share on other sites
np. The "c" is supposed to be transparent, with no black box around it.

Sandman: there is? I thought SDL_SetColorKey would render any pixel with the given color key transparent, that's what it says in the SDL documentation.

Share this post


Link to post
Share on other sites
Unfortunatly, SDL isn't rendering your c. OpenGL is.

"SDL's Implementation of OpenGL" does not exist. SDL is nothing more than a wrapper around window creation code, like WGL, when using OpenGL. All your opengl calls still go to whatever implementation you have installed.

Despite all that, your manual alpha-setting code should work (Though I didn't actually read it, the idea is perfectly sound)

You'd probably be best off just loading 32 bit tgas. They will let you do stuff colorkeying just can't, like translucent things.

Share this post


Link to post
Share on other sites
Quote:
Original post by Deyja
Unfortunatly, SDL isn't rendering your c. OpenGL is.

"SDL's Implementation of OpenGL" does not exist. SDL is nothing more than a wrapper around window creation code, like WGL, when using OpenGL. All your opengl calls still go to whatever implementation you have installed.

Despite all that, your manual alpha-setting code should work (Though I didn't actually read it, the idea is perfectly sound)

You'd probably be best off just loading 32 bit tgas. They will let you do stuff colorkeying just can't, like translucent things.


agreed.

Share this post


Link to post
Share on other sites
Ok, ^_^ I got it working. I used my manual color keying for loop again, and it worked. The thing was, it worked before, but I didn't immediately recognize it. Guess why? I set the character 'c' to white, and I forgot about it, so when it worked, it rendered the white c on the white background, so thought it didn't work. So I had to scrap some code.

Well for future refrence, or for anybody trying to get colory keying work:


int load_texture(s_texture_ptr texture,char* filename,Uint8 r,Uint8 g,Uint8 b)
{
if (!texture)
{
printf ("Invalid texture pointer passed while attempting to load %s\n",filename);
return 0;
}

SDL_Surface* surf,*newsurf;

surf = IMG_Load(filename);

if (!surf)
{
printf ("Unable to load %s\n",filename);
return 0;
} //end if

//now convert to OpenGL
//do some mathemagic
SDL_PixelFormat targetfmt; /*the target format*/

targetfmt.palette = NULL;
targetfmt.BitsPerPixel = 32; /*32 bits per pixel*/
targetfmt.BytesPerPixel = 4; /*a whopping four bytes per pixel*/

targetfmt.Rmask = 0x000000ff;
targetfmt.Gmask = 0x0000ff00;
targetfmt.Bmask = 0x00ff0000;
targetfmt.Amask = 0xff000000;

newsurf = SDL_ConvertSurface(surf,&targetfmt,SDL_SRCCOLORKEY);

if (!newsurf)
{
printf ("Error converting %s to 32-bit surface\n",filename);
return 0;
}

/*success*/
Uint8* pix = (Uint8*)newsurf->pixels;

for (int y=0;y<newsurf->h;y++) {
for (int x=0;x<newsurf->pitch;x+=4) {
int loc = x+(y*newsurf->pitch);
if (pix[loc] == r && pix[loc+1] == g && pix[loc+2] == b) {
pix[loc+3] = 0;
}
}
}

//now we rock
glGenTextures(1,&texture->texture);

glBindTexture(GL_TEXTURE_2D,texture->texture);

//filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D,0,4,newsurf->w,newsurf->h,0,GL_RGBA,GL_UNSIGNED_BYTE,newsurf->pixels);

texture->width = newsurf->w;
texture->height = newsurf->h;

SDL_FreeSurface(newsurf);
SDL_FreeSurface(surf);

printf ("Loading %s successful\n",filename);

return 1; /*scucess*/
}



thanks for your input guys!

Share this post


Link to post
Share on other sites

This topic is 4859 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this