Jump to content
  • Advertisement
Sign in to follow this  
Flustration

OpenGL Textures displaying solid backgrounds instead of transparent pixels

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

Hello, all. I am getting red backgrounds on my textures which should be transparent...

Here are my source image files:

http://dl.dropbox.co.../slider_bar.tga
http://dl.dropbox.co...ider_slider.tga

Here are all my OpenGL options:

glEnable( GL_TEXTURE_2D );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glEnable(GL_BLEND);
glAlphaFunc(GL_NOTEQUAL, 1);
glEnable(GL_ALPHA_TEST);
glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f);
glViewport( 0, 0, 900, 600 );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(0.0f, 900, 600, 0.0f, -1.0f, 1.0f);
glMatrixMode( GL_MODELVIEW );
glScalef(1, -1, 1);
glDisable(GL_DEPTH_TEST);
glLoadIdentity();


Here is my texture loading/initialization code:

texture::texture(SDL_Surface *rawSurface)
{
if(listInitialized == false)
{
initList();

}

for(int a = 0; a < 256; a++)
{
if(textureFree[a] == true)
{

glTexture = a;
numTextures++;
textureFree[a] = false;
break;
}
}

SDL_PixelFormat pixF = *rawSurface->format;
std::cout << "BPP : " << (int) pixF.BytesPerPixel;

SDL_Surface *surface;

textureRect.w = nextPowerOfTwo(rawSurface->w);
textureRect.h = nextPowerOfTwo(rawSurface->h);
textureRect.x = 0;
textureRect.y = 0;

imageRect.w = rawSurface->w;
imageRect.h = rawSurface->h;
imageRect.x = 0;
imageRect.y = 0;

paddingW = textureRect.w - imageRect.w;
paddingH = textureRect.h - imageRect.h;

//where within the texture surface is the actual image?
SDL_Rect rectDestination;
rectDestination.w = imageRect.w;
rectDestination.h = imageRect.h;
rectDestination.x = paddingW;
rectDestination.y = paddingH;

GLint nOfColors = rawSurface->format->BytesPerPixel;
GLenum texture_format;

if (nOfColors == 4) // contains an alpha channel
{
if (rawSurface->format->Rmask == 0x000000ff)
{
std::cout << "format RGBA\n";
texture_format = GL_RGBA;
}
else
{
std::cout << "format BGRA\n";
texture_format = GL_BGRA;
}

} else if (nOfColors == 3) // no alpha channel
{
if (rawSurface->format->Rmask == 0x000000ff)
{
std::cout << "format RGB\n";
texture_format = GL_RGB;

}
else
{
std::cout << "format BGR\n";
texture_format = GL_BGR;
}

}

surface = SDL_CreateRGBSurface(SDL_SWSURFACE, textureRect.w , textureRect.h , 32, rawSurface->format->Rmask, rawSurface->format->Gmask, rawSurface->format->Bmask, rawSurface->format->Amask);
SDL_FillRect(surface, &textureRect, SDL_MapRGBA(surface->format, 255, 0, 0, 9));
SDL_SetAlpha(rawSurface, 0, SDL_ALPHA_OPAQUE);
SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
SDL_BlitSurface(rawSurface, &imageRect, surface, &rectDestination);
SDL_SetAlpha(rawSurface, SDL_SRCALPHA, 0);
SDL_SetAlpha(surface, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);

glBindTexture(GL_TEXTURE_2D, textureBank[glTexture]);
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, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels);

if(surface)
{SDL_FreeSurface( surface );}
}


and finally, rendering...

void texture::drawTexture(int x, int y)
{
x = x - paddingW;
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, textureBank[glTexture] );
glColor4f(1,1,1,1);
glBegin( GL_QUADS );
//Bottom-left vertex (corner)
glTexCoord2i( 0, 0 );
glVertex3f( x, (y + textureRect.h), 0.0f );

//Bottom-right vertex (corner)
glTexCoord2i( 1, 0 );
glVertex3f( (x + textureRect.w), (y + textureRect.h), 0.f );

//Top-right vertex (corner)
glTexCoord2i( 1, 1 );
glVertex3f( (x + textureRect.w), y, 0.f );

//Top-left vertex (corner)
glTexCoord2i( 0, 1 );
glVertex3f( x, y, 0.f );
glEnd();
}


And my output...

AS6RM.png

Halp smile.png Thanks

Share this post


Link to post
Share on other sites
Advertisement

glAlphaFunc(GL_NOTEQUAL, 1);
glEnable(GL_ALPHA_TEST);

by this code, pixels which have alpha:255 they will be invisible (ignored from drawing)... So, drop them...

glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);

this function will not give you "transparent" effect as you expecting.
use this:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Now, looking at images I see, they are 32-bit but their alpha channel filled with zero values (invisible)...
Best wishes, FXACE. Edited by FXACE

Share this post


Link to post
Share on other sites
All right, here goes.

First, I tried just changing that line.



glEnable( GL_TEXTURE_2D );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glAlphaFunc(GL_NOTEQUAL, 1);
glEnable(GL_ALPHA_TEST);


I got this output (there are barely-visible blue pixels where there should be transparency).

QVBMj.png

So then, I changed the alpha func around...:

glAlphaFunc(GL_GREATER, 0);

But I got this output:

http://i.imgur.com/QVBMj.png

totally black!

Share this post


Link to post
Share on other sites
Okay, I see that the red pixels were actually ENTIRELY by my own hand... however, I cannot get blending to actually work. When I swap thevalues in glBlendFunc call, I get a black screen BTW.

vblF2.png Edited by Flustration

Share this post


Link to post
Share on other sites
Nothing changed...
Again, let's check your "http://dl.dropbox.co...ider_slider.tga" (for example):
h6s08.jpg
Here, we see your image in photoshop and how much each channel (red,green,blue,alpha) filled. Now, are you not see that alpha channel is filled by black color (not visible)?
Now, let's imagine this image in your code:

glBlendFunc(/* src factor */GL_ONE_MINUS_SRC_ALPHA, /* dst factor */GL_SRC_ALPHA);

And put the values together:
dst.rgb = src.rgb * (1-src.a) + dst.rgb * src.a; : where "src" - "texel of your image" * "glColor", "dst" - OpenGL's color buffer.
Now, each pixel (of your image) in alpha channel has 0.0 (black). If to put this value into this formula it would be:
dst.rgb = src.rgb; which looks like "blend is disabled".
Now, useless code:

glAlphaFunc(GL_NOTEQUAL, 1);
glEnable(GL_ALPHA_TEST);

In fact, this will never fail with your image. Alpha test is used for to draw the pixels into buffer if their alpha channel passes "glAlphaFunc" condition.

Now, how to solve this:
First of all, you need to do something with you images (to paint into their alpha channel):
3SkoV.jpg
"I have just copied values from blue channel to alpha channel"...
Next, it's would be enough to do:

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

When you done everything with blending mode do this:

glDisable(GL_BLEND);

Usually this is need, because when you would draw some objects without blend, you would get some "unexpected blended pixels", and the reason would be "you forgot to disable blending mode".
Also, you don't need there GL_ALPHA_TEST.

Another thing:
It would be much better if you put "GL_RGBA" instead of "4" in "internalFormat" parameter of "glTexImage2D", not only for my eyes but for OpenGL too.

Best wishes, FXACE. Edited by FXACE

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!