Page 1 of 1

[SOLVED]Opengl Alpha Test

Posted: Thu Apr 07, 2011 10:35 pm
by like80ninjas
I can't get alpha testing to work on my sprites. They are either black where the transparency should be or the whole screen is the clear color.

Code: Select all

	
        SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
 
	SDL_Surface* screen = SDL_SetVideoMode( width, height, 32, SDL_OPENGL );
	
	glEnable( GL_TEXTURE_2D );
	glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
	glViewport( 0, 0, width, height );
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	glOrtho(0.0f, width*1.5, height*1.5, 0.0f, -100.0f, 100.0f);
	glMatrixMode( GL_MODELVIEW );

	glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE);
	glClearDepth(1.0f);

	glColor4f(1.0f,1.0f,1.0f,1.0f);
	glAlphaFunc( GL_GREATER, 0.1f );
	glEnable( GL_ALPHA_TEST );
That is my setup and here is how I load a texture, partially based off of lazyfoo

Code: Select all

	//The image that's loaded
    SDL_Surface* loadedImage = NULL;
    
    //The optimized image that will be used
    SDL_Surface* optimizedImage = NULL;
    
    //Load the image using SDL_image
    loadedImage = IMG_Load( filename.c_str() );
    
    //If the image loaded
    if( loadedImage != NULL )
    {
        //Create an optimized image
        optimizedImage = SDL_DisplayFormat( loadedImage );
        
        //Free the old image
        SDL_FreeSurface( loadedImage );
    

    //Return the optimized image
	texture_image[current_image] = optimizedImage;

	// Have OpenGL generate a texture object handle for us
	glGenTextures( 1, &texture[current_image] );
 
	// Bind the texture object
	glBindTexture( GL_TEXTURE_2D, texture[current_image] );
 
	// Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
 
	// Edit the texture object's image data using the information SDL_Surface gives us
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, optimizedImage->w, optimizedImage->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, optimizedImage->pixels );
I've done all of this many times before but for some reason I just can't get it to work this time.. Also i'm using .PNG's created by paint.net and I had to switch the second format parameter in glTexImage2D to GL_BGRA or it would display my colors as opposites, I suck at gl can anyone help me clear this issue up and maybe help me fix anything else i'm doing poorly?

Re: Opengl Alpha Test

Posted: Thu Apr 07, 2011 11:00 pm
by Nokurn
Assuming that what you want is for your textures to have translucent pixels, this bit

Code: Select all

glAlphaFunc( GL_GREATER, 0.1f );
glEnable( GL_ALPHA_TEST );
should be

Code: Select all

glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_BLEND );
See the documentation for glAlphaFunc() and glBlendFunc() if you're interested in finding out why. I would also recommend reading chapter 15 of the OpenGL FAQ, as it answers pretty much all beginner questions about transparency.

Re: Opengl Alpha Test

Posted: Thu Apr 07, 2011 11:03 pm
by like80ninjas
I want alpha testing and not blending, not only that, but changing those lines to the ones you suggested make the sprites not appear, just like the alpha testing issue.

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 12:31 am
by Nokurn
My mistake.

Add this before your call to SDL_SetVideoMode():

Code: Select all

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL doesn't always set you up with an alpha channel when you create an OpenGL-enabled window.

Remove this line:

Code: Select all

optimizedImage = SDL_DisplayFormat( loadedImage );
And then upload your texture with GL_RGBA instead of GL_BGRA. Your display is likely in BGRA format. This is why you had to use GL_BGRA as the source pixel format rather than SDL_RGBA. Calling SDL_DisplayFormat() will flip the bytes around so that the pixel format matches that of your device, allowing faster blitting. This is unimportant when using the texture with OpenGL because you aren't directly blitting the pixel data. It may even cause inconsistent behavior across different computers.

Hope this helps.

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 12:48 am
by like80ninjas
I've added those lines, and tried your suggestions and it's still the same thing, nothing draws.
Also, when I remove the line you said it ends up not loading the textures ( the quads show up as white with no texture ), so that doesn't fix the BGR problem.


To be perfectly clear my issue is, that I wanna use Alpha Testing to remove the alpha section of my .PNG (I have done this before, just don't remember how I got it all running), but when I enable alpha testing, nothing draws at all.
Secondly, I was curious about why my glTexImage2D requires BGRA. The changes you suggestion had no effect on this.

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 1:01 am
by Nokurn
like80ninjas wrote:I've added those lines, and tried your suggestions and it's still the same thing, nothing draws.
Also, when I remove the line you said it ends up not loading the textures ( the quads show up as white with no texture ), so that doesn't fix the BGR problem.


To be perfectly clear my issue is, that I wanna use Alpha Testing to remove the alpha section of my .PNG (I have done this before, just don't remember how I got it all running), but when I enable alpha testing, nothing draws at all.
Secondly, I was curious about why my glTexImage2D requires BGRA. The changes you suggestion had no effect on this.
What are you using for GL_TEXTURE_ENV_MODE?

I forgot to mention that if you take out the SDL_DisplayFormat() call and change GL_BGRA to GL_RGBA, you would have to also remove the call to SDL_FreeSurface(loadedImage), and use loadedImage in place of optimizedImage in the glTexImage2D() call and texture_image assignment, like so:

Code: Select all

   //The image that's loaded
    SDL_Surface* loadedImage = NULL;
    
    //Load the image using SDL_image
    loadedImage = IMG_Load( filename.c_str() );
    
    //If the image loaded
    if( loadedImage != NULL )
    {
    //Return the optimized image
   texture_image[current_image] = loadedImage;

   // Have OpenGL generate a texture object handle for us
   glGenTextures( 1, &texture[current_image] );

   // Bind the texture object
   glBindTexture( GL_TEXTURE_2D, texture[current_image] );

   // Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

   // Edit the texture object's image data using the information SDL_Surface gives us
   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, loadedImage->w, loadedImage->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, loadedImage->pixels );
Sleeping pills = sloppy explanations.

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 1:06 am
by like80ninjas
Of course, I figured that's what you meant, otherwise it would just crash. So I've already tried that. I also haven't set up GL_TEXTURE_ENV_MODE, but I've never used that before and had this working in a previous engine, I must be doing something really simple wrong.

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 1:58 am
by Nokurn
I'm pretty much stumped. The only thing I can think of is perhaps an issue with your texture.

I put together a quick test to see if I could replicate the issue, but I could not. Here is the code I used:

Code: Select all

#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#ifdef __APPLE__
#	include "SDL_image/SDL_image.h"
#else
#	include "SDL/SDL_image.h"
#endif

const int width = 1024;
const int height = 768;
SDL_Surface *screen;
GLuint texture;
bool running = true;

GLuint SurfaceToTexture(const char *fileName)
{
	SDL_Surface *surface = IMG_Load(fileName);
	if (surface == NULL)
		return 0;
	
	GLuint result;
	glGenTextures(1, &result);
	glBindTexture(GL_TEXTURE_2D, result);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels);
	
	SDL_FreeSurface(surface);
	
	return result;
}

inline void Draw()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	
	glBindTexture(GL_TEXTURE_2D, texture);
	glColor4ub(255, 255, 255, 255);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f);
	glVertex2f(0.0f, 0.0f);
	glTexCoord2f(1.0f, 0.0f);
	glVertex2f(128.0f, 0.0f);
	glTexCoord2f(1.0f, 1.0f);
	glVertex2f(128.0f, 128.0f);
	glTexCoord2f(0.0f, 1.0f);
	glVertex2f(0.0f, 128.0f);
	glEnd();
	
	SDL_GL_SwapBuffers();
}

int main(int argc, char **argv)
{
	if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
		return 0;
	atexit(SDL_Quit);
	
	if (IMG_Init(IMG_INIT_PNG) == -1)
		return 0;
	atexit(IMG_Quit);
	
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	
	screen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
	if (screen == NULL)
		return 0;
	SDL_WM_SetCaption("GLSDL", NULL);
	
	glEnable(GL_ALPHA_TEST);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	glAlphaFunc(GL_GREATER, 0.1f);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClearDepth(1.0f);
	glDepthMask(GL_TRUE);
	glDepthFunc(GL_LEQUAL);

	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
	glMatrixMode(GL_MODELVIEW);
	
	texture = SurfaceToTexture("GLSDL.png");
	
	while (running) {
		SDL_Event event;
		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT)
				running = false;
		}
		
		Draw();
	}
	
	return 0;
}
And here is the texture:
Image

Hope this helps.

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 3:52 am
by like80ninjas
I rewrote some of my code to be like yours and it still had the same issue. I'm thinking it might be an issue with my texture? I don't see how that could be though, I literally just saved a .PNG like I always do...


Edit* I tried using the texture you supplied and it's the same deal, NOTHING will display when Alpha testing is turned on. I really don't understand this. I also tried copy pasting most of the code you supplied and none of it helps. If I turn on alpha testing no matter how I set it up it just wont render.

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 9:09 am
by Nokurn
like80ninjas wrote:I rewrote some of my code to be like yours and it still had the same issue. I'm thinking it might be an issue with my texture? I don't see how that could be though, I literally just saved a .PNG like I always do...


Edit* I tried using the texture you supplied and it's the same deal, NOTHING will display when Alpha testing is turned on. I really don't understand this. I also tried copy pasting most of the code you supplied and none of it helps. If I turn on alpha testing no matter how I set it up it just wont render.
If you create a completely new project and use ONLY the code and texture I supplied, does it render?

Re: Opengl Alpha Test

Posted: Fri Apr 08, 2011 2:01 pm
by like80ninjas
I didn't do that, but I did create a new project for my game last night, and just added all of my files back into it, and it works... So Idk, solved I guess?

Re: [SOLVED]Opengl Alpha Test

Posted: Thu Apr 21, 2011 6:16 pm
by superLED
I think you have had the same issue I've had a lot of times before.
When 2 dudes and I were making a game together at the Global Game Jam, I had a bug with some movements of the player.
I knew what went wrong, fixed it, but it didn't work. Tried 1000 different changes, and nothing worked.

Then I finally tried to click "Rebuild", and bam, it worked.

If you are using Visual Studio, some files may not be rebuilt for some reason, and you have to force a rebuild.
(I guess it thinks no major changes has been done, so it just ignore rebuilding that cpp file.)