Problems with transparency/blending, .pngs, and SDL_image
I'll throw one suggestion with arekkusu's original code; put a break-point directly after the switch to inspect the values of "img_format", "img_type", and "internal_format"; if I remember correctly, without converting the resulting surface, SDL_image defaults to loading files as 24bpp, which doesn't support blending.
(although as I've never upgraded the install of SDL_image on my system, this may have changed, in which case ignore the above
)
(although as I've never upgraded the install of SDL_image on my system, this may have changed, in which case ignore the above
)
Mark Bishop
I decided to come back to this after working with OpenGL more to understand it better (as at the time this thread started I had been coding with OpenGL for less than a month). The code arekkusu posted works at about 99% satisfaction for me. My .tga has it's transparency and everything but so far I've noticed a bug:
When loading .tga it replaces blue with red, red with blue, but leaves green alone.
Can someone help me find where it's reversing these?
When loading .tga it replaces blue with red, red with blue, but leaves green alone.
Can someone help me find where it's reversing these?
You can reverse the red & blue components with this:
(where _imageData is the pointer to your data & bytesPerPixel == 4)
Or, you could change img_format to GL_BGRA.
Anyway, why not PNG?
PHP Code:
// BGRA -> RGBA
for (i=0; i<(long)imageSize; i+=bytesPerPixel)
{
tmp = _imageData[i];
_imageData[i] = _imageData[i + 2];
_imageData[i + 2] = tmp;
}
(where _imageData is the pointer to your data & bytesPerPixel == 4)
Or, you could change img_format to GL_BGRA.
Anyway, why not PNG?
I don't know why not PNG. I could try it. It was simply that TGA was the first file to work and I didn't want it to stop working. Sounds stupid, is stupid. I'll try PNG and see what the results are. Thanks for the conversion though.
I tried PNG and the color is perfect, but I lose transparencies. I'm going to try a few things on my own (involving Photoshop and how I make the images) but if anything is wrong in the code that would stop PNGs from having transparencies, please let me know.
Also will this code allow me to use partial transparencies (0<alpha<1) or is it 1 or 0?
Also will this code allow me to use partial transparencies (0<alpha<1) or is it 1 or 0?
Ok now here's a weird occurance:
If I put my image loading code in like this:
It works just fine but if I put it in this order:
It switches around so texturing with the ID of T_CRATE actually shows me the T_WALL image.
Any ideas why? It is making this very hard for me. Also when I try to texture with T_GROUND, I don't get a texture drawn. Below is the loading code:
If I put my image loading code in like this:
Code:
enum { T_LOGO=1, T_CRATE, T_WALL, T_GROUND };
CreateTexture2D(texID[T_CRATE],
texWidth[T_CRATE],
texHeight[T_CRATE],
"crate.png");
CreateTexture2D(texID[T_WALL],
texWidth[T_WALL],
texHeight[T_WALL],
"brick.png");
CreateTexture2D(texID[T_GROUND],
texWidth[T_GROUND],
texHeight[T_GROUND],
"ground.png");Code:
enum { T_LOGO=1, T_CRATE, T_WALL, T_GROUND };
CreateTexture2D(texID[T_WALL],
texWidth[T_WALL],
texHeight[T_WALL],
"brick.png");
CreateTexture2D(texID[T_CRATE],
texWidth[T_CRATE],
texHeight[T_CRATE],
"crate.png");
CreateTexture2D(texID[T_GROUND],
texWidth[T_GROUND],
texHeight[T_GROUND],
"ground.png");Any ideas why? It is making this very hard for me. Also when I try to texture with T_GROUND, I don't get a texture drawn. Below is the loading code:
Code:
signed int CreateTexture2D(GLuint &theTextureId,
Uint16 &theTextureWidth,
Uint16 &theTextureHeight,
const char *theTextureImagePath)
{
SDL_Surface *theTextureSurface;
if(( theTextureSurface = IMG_Load( theTextureImagePath )) == NULL )
{
fprintf( stderr,IMG_GetError());
cout << "Could not load file '" << theTextureImagePath << "'" << endl;
return -1;
}
SDL_LockSurface( theTextureSurface );
theTextureWidth = theTextureSurface->w;
theTextureHeight = theTextureSurface->h;
GLvoid *theTextureImage = theTextureSurface->pixels;
GLenum internal_format;
GLenum img_format, img_type;
switch (theTextureSurface->format->BitsPerPixel)
{
case 32:
img_format = GL_RGBA;
img_type = GL_UNSIGNED_BYTE;
internal_format = GL_BGRA;
break;
case 24:
img_format = GL_RGB;
img_type = GL_UNSIGNED_BYTE;
internal_format = GL_RGB8;
break;
case 16:
img_format = GL_RGBA;
img_type = GL_UNSIGNED_SHORT_5_5_5_1;
internal_format = GL_RGB5_A1;
break;
default:
img_format = GL_LUMINANCE;
img_type = GL_UNSIGNED_BYTE;
internal_format=GL_LUMINANCE8;
break;
}
glGenTextures( 1, &theTextureId );
glBindTexture( GL_TEXTURE_2D, theTextureId );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D( GL_TEXTURE_2D, 0, internal_format,
theTextureWidth, theTextureHeight, 0,
img_format, img_type, theTextureImage );
SDL_UnlockSurface( theTextureSurface );
SDL_FreeSurface( theTextureSurface );
return 0;
}Nick Wrote:Ok now here's a weird occurance:
If I put my image loading code in like this:
[...]
It works just fine but if I put it in this order:
[...]
It switches around so texturing with the ID of T_CRATE actually shows me the T_WALL image.
Any ideas why? It is making this very hard for me. Also when I try to texture with T_GROUND, I don't get a texture drawn.
Just guessing but:
First, I'm assuming you also have CreateTexture2D(texID[T_LOGO],...) somewhere before.
texID is an array that stores your texture IDs so if by mistake you are doing
Code:
glBind(GL_TEXTURE2D, T_CRATE)Code:
glBind(GL_TEXTURE2D, texID[T_CRATE])Your enum starts at 1 (bad idea, since you are wasting the element 0 of the texID array this way!) so in your first code, texID[T_LOGO] gets assigned a 1 by CreateTexture2D (the assignment is done in the line "glGenTextures( 1, &theTextureId );" which gives you the first empty texture id, initially 1), which happens to make texID[T_LOGO] == 1 == T_LOGO.
The other elements of the array also end up like that:
texID[T_CRATE] == 2 == T_CRATE,
texID[T_WALL] == 3 == T_WALL and
texID[T_GROUND] == 4 == T_GROUND.
On your second code, that lucky coincidence doesn't happen, so you get
texID[T_LOGO] == 1 == T_LOGO.
texID[T_WALL] == 2 == T_CRATE,
texID[T_CRATE] == 3 == T_WALL and
texID[T_GROUND] == 4 == T_GROUND.
So, check that wherever you use glBind, you use glBind(GL_TEXTURE2D, texID[T_CRATE]) instead of glBind(GL_TEXTURE2D, T_CRATE), and so on, as I mentioned above.
Of course, maybe the bug is somewhere else
Yeah I feel kinda dumb. I realized I was forgetting the texID[] part when setting textures but thanks for realizing it. I'm glad some people are smart enough to help people like me.
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Sprite transparency in OpenGL? | Guest! | 26 | 24,436 |
Feb 17, 2012 09:24 AM Last Post: Skorche |
|
| 2d shadow blending problems | tesil | 1 | 4,750 |
Mar 17, 2011 10:12 AM Last Post: Skorche |
|
| Trouble using SDL_image with XCode 3.2.3 Snow Leopard | code4fun | 1 | 3,640 |
Sep 22, 2010 10:47 PM Last Post: OneSadCookie |
|
| OpenGL ES 2.0, 2D Alpha Transparency Artifacts | Macmenace | 3 | 6,223 |
Mar 28, 2010 11:18 PM Last Post: AnotherJake |
|
| SDL_image and bmp loading | Duane | 13 | 7,444 |
Dec 21, 2009 09:14 AM Last Post: Skorche |
|

