Sign in to follow this  
d h k

[SDL_image+OpenGL] every format EXCEPT .tif works... [SOLVED]

Recommended Posts

Hello, I'm using SDL with the SDL_image-library plus OpenGL to render a tile-based isometric RTS-game. SDL_image's IMG_Load-function is what I am using. It only expects a path- or filename as argument and then automatically analyzes the file-format and loads the image. This is my core sprite::init-function and how it makes use of the above mentioned part:
void csprite::init ( const char *filename )
// initializes the sprite
{
	SDL_Surface *image, *temp;
	int x = 0, y = 0, w, h;
	SDL_Rect area;
	unsigned int texture;

	// load image
	image = IMG_Load ( filename );

	// if there was an error
	if ( image == NULL )
		// return error
		return_error ( "Failed to load bitmap..." );
   
	// set color key
	SDL_SetColorKey ( image, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB ( image->format, 255, 0, 128 ) );

	// set width and height
	width = image->w;
	height = image->h;
	w = power_of_two ( width );
	h = power_of_two ( height );

	// set texture coordinates
	texture_coordinate[0][0] = 0.0f;
	texture_coordinate[1][0] = 0.0f;
	texture_coordinate[2][0] = ( float ) width / w;
	texture_coordinate[3][0] = ( float ) height / h;

	// blit from bitmap to a temporary surface with 32 bits per pixel
	temp = SDL_CreateRGBSurface ( SDL_SWSURFACE, w, h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 );

	if ( temp == NULL )
	// if there was an error
		// return error
		return_error ( "Failed to create temporary surface..." );

	// set up rectangle
	area.x = x * width;
	area.y = y * height;
	area.w = width;
	area.h = height;
      
	if ( SDL_BlitSurface ( image, &area, temp, NULL ) == -1 )
	// if there is an error
		// return error
		return_error ( "Failed to blit bitmap to temporary surface..." );

	// create texture
	glGenTextures ( 1, &texture );
	glBindTexture ( GL_TEXTURE_2D, texture );
      
	if ( temp->pixels == NULL )
	// if there was an error
		// return error
		return_error ( "Failed to create texture..." );

	if ( SDL_MUSTLOCK ( temp ) )
	// if temporary surface must be locked
		// lock temporary surface
		SDL_LockSurface(temp);

	// turn bitmap into texture
	glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp->pixels );

	if ( SDL_MUSTLOCK ( temp ) )
	// if temporary surface had to be locked
		// unlock temporary surface again
		SDL_UnlockSurface ( temp );

	// set texture filtering
	glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

	// store texture number
	texture_number[0] = texture;

	// free temporary surface
	SDL_FreeSurface ( temp );

	// free image
	SDL_FreeSurface ( image );
}




Pretty straight-forward, I guess. Now, this works and loads all kinds of formats into OpenGL-textures which can then be assigned to triangle-strips and look like perfect sprites (although I didn't try .jpeg, because it really doesn't fit into a game), EXCEPT .tif and that is my very best choice, because it supports an alpha-channel, which I need. Of course, there's still .png, but it turns out that I can't properly save as .png with alpha-channel (but SDL_image will work with .png). Before I had that code in sprite::init, I just used SDL with SDL_image and without OpenGL and back then, .tif-files did work beautifully with alpha-channel by just replacing SDL_LoadIMG with Load_IMG from SDL_image. Why does it now, with OpenGL, suddenly not work. Any help is greatly appreciated! [Edited by - d h k on May 26, 2007 9:44:26 AM]

Share this post


Link to post
Share on other sites
I think you'll need to put "SDL_SetAlpha(image, 0, 0);" just before you blit the image surface to the temp one. This is because you want to just copy the alpha of the image surface, rather than have image masked by the temp surface (which may well be completely transparent).

This is one of the most useful pages of the SDL docs IMO, (in your case I think the second note at the bottom is relevant).

Share this post


Link to post
Share on other sites
Thanks, that renders the .tif-files correctly now, you were right.

However, now, they are not drawn with alpha-buffer. How can I use the alpha-buffer with those files correctly?

Share this post


Link to post
Share on other sites
Quote:
Original post by d h k
Thanks, that renders the .tif-files correctly now, you were right.

However, now, they are not drawn with alpha-buffer. How can I use the alpha-buffer with those files correctly?


Well, you'll need to turn blending on in OpenGL, as well, with something like this:


glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Share this post


Link to post
Share on other sites
Wow, that was dumb of me to ask. It works beautifully. Very nice! :)

Thanks a lot.

Share this post


Link to post
Share on other sites

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