Results 1 to 5 of 5

Thread: glBlendFunc() problem

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2011
    Posts
    5

    glBlendFunc() problem

    Hi all,
    I'm making a simple 2d game in SDL and openGL (converting SDL surfaces to GL textures for the sprites). All was going fine until I started trying to add in some color keying.

    The problem is when calling glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) the screen gets blanked to whatever the clear screen color is. When I call blending with GL_ZERO I just get a black rectangular square where the sprite should be. I found a thread elsewhere with a similar problem to mine
    (http://www.gamedev.net/topic/556601-...screen-solved/)
    and in this calling SDL_SetAlpha to make sure the SDL surface is opaque worked - but unfortunately not the same for me. Still nothing.

    Has anyone got any ideas?

    Much appreciated.

  2. #2
    Senior Member Regular Contributor
    Join Date
    Oct 2010
    Location
    France
    Posts
    458

    Re: glBlendFunc() problem

    Do you initialize an RGBA OpenGL context (and not RGB only) ? Do you enable blending ? Do you render in the good order ? Do you clear the buffer with all rgba good values ?

    If yes, post more details, for example code snippets.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2011
    Posts
    5

    Re: glBlendFunc() problem

    Hi, thanks for your response -
    In answer to your queries.

    I'm pretty sure I initialize an RGBA context - it's possible I'm wrong though - have thus far about three days experience with this. Will chuck all the pertient code down at the end of this...

    Yes I do enable blending.
    Code :
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    - It's actually turning this on that seems to be the source of my problems. With it diabled my sprites render fine (albeit without transparency)

    - Think I render in a good order. Clear the screen then render sprites right?

    - Not sure what you mean be 'clear the buffer with all rgba good values' - if you mean are all my textures RGBA when rendered then yes - otherwise not sure what you mean?

    Anyway code is as follow (btw am using SDL_Opengl - don't know if this is a problem?)

    All the initialization stuff:

    Code :
     
    cGraphics::cGraphics(int WindowWidth, int WindowHeight, int WindowBPP, string WindowCaption)
    {
        //initialize all SDL subsystems
        SDL_Init(SDL_INIT_VIDEO);	
     
        //Initialize SDL_ttf
        TTF_Init();
     
    	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
     
    	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 );
     
     
        //Set up the screen
    	screen = SDL_SetVideoMode(WindowWidth, WindowHeight, WindowBPP, SDL_OPENGL );//SDL_FULLSCREEN);
     
        //Set the window caption
        SDL_WM_SetCaption(WindowCaption.c_str(), NULL);
     
    	glEnable(GL_TEXTURE_2D);
     
    	glEnable(GL_BLEND);
    	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     
    	//Clear the screen to red
    	glClearColor( 255.0f, 0.0f, 0.0f, 0.0f );
     
    	//Set the viewport to the size of the window
    	glViewport( 0, 0, WindowWidth, WindowHeight);
    	//glViewport( 0, 0, 640, 480);
     
    	glClear(GL_COLOR_BUFFER_BIT);
     
    	glMatrixMode( GL_PROJECTION );
    	glLoadIdentity();
     
    	glOrtho(0.0f, WindowWidth, WindowHeight, 0.0f, -1.0f, 1.0f);
    	//glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f);
     
    	glMatrixMode( GL_MODELVIEW );
    	glLoadIdentity();
    }

    reading in the sdl surfaces + converting into textures

    Code :
     
    SDL_Surface* cGraphics::load_image_SDL(string filename)
    {
        //The image that's loaded
        SDL_Surface* loadedImage = NULL;
     
        //The optimized image that will be used
        SDL_Surface* optimizedImage = NULL;
     
        //Load the 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);
            //If the image was optimized just fine
            if (optimizedImage != NULL)
            {
                //Map the color key
                //Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF);
     
                //Set all pixels of color [0,0xFF,0xFF] to be transparent
                //SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
            }
        }
     
        //Return the optimzed image
        return optimizedImage;
    }
     
    spriteStruct cGraphics::load_texture(std::string filename)
    {
    	GLuint texture;			// This is a handle to our texture object
    	SDL_Surface *testSurface;	// This surface will tell us the details of the image
    	SDL_Surface *surface;  //The final surface to be converted to gl texture
    	GLenum texture_format;
    	GLint  nOfColors;
     
    	testSurface = load_image_SDL(filename);	
     
     
    	unsigned width;
    	unsigned height;
     
    	if (SDL_MUSTLOCK(testSurface))
    		SDL_LockSurface(testSurface);
     
    	for(int  i = 0; i < testSurface->w; i++ )
    	{
    		for (int j = 0; j < testSurface->h; j++)
    		{
     
    			Uint8 r;
    			Uint8 g;
                Uint8 b;
    			Uint8 a;
                Uint32 onePixel = get_pixel32(testSurface, i, j);
    			SDL_GetRGBA(onePixel, testSurface->format, &amp;r, &amp;g, &amp;b, &amp;a);  
    			if (r ==0 &amp;&amp; g == 255 &amp;&amp; b == 255)
                {
    				// if so, then set alpha to transparent
                    a = 0;
                 }
    			 else a = 255;
                 Uint32 newPixel = SDL_MapRGBA(testSurface->format, r, g, b, a);
                 put_pixel32(testSurface, i, j, newPixel);
     
    			 onePixel = get_pixel32(testSurface, i, j);
    			 SDL_GetRGBA(onePixel, testSurface->format, &amp;r, &amp;g, &amp;b, &amp;a);
    			 SDL_GetRGBA(onePixel, testSurface->format, &amp;r, &amp;g, &amp;b, &amp;a);
    		}
    	}
     
    	if (SDL_MUSTLOCK(testSurface))
    		SDL_UnlockSurface(testSurface);
     
    	if ( ( (testSurface->w != 0) &amp;&amp; ( (testSurface->w & (testSurface->w - 1) )!=0 ) ) || 
    		 ( (testSurface->h != 0) &amp;&amp; ( (testSurface->h & (testSurface->h - 1) )!=0 ) ) )
    	{
    		printf("Warning: texture width/depth is not a power of two");
     
    		width  = pow( 2, ceil( log10(static_cast<double>(testSurface->w) ) / log10(static_cast<double>(2) ) ) );
    		height = pow( 2, ceil( log10(static_cast<double>(testSurface->h) ) / log10(static_cast<double>(2) ) ) );
     
    		surface = SDL_CreateRGBSurface(testSurface->flags, 
    									   width, 
    									   height,
    								       testSurface->format->BitsPerPixel,
    									   testSurface->format->Rmask,
    									   testSurface->format->Gmask,
    									   testSurface->format->Bmask,
    									   testSurface->format->Amask);
     
    		SDL_BlitSurface(testSurface, NULL, surface, NULL);
    		SDL_Flip(surface);
     
    	}
    	else
    	{
    		surface = testSurface;
    		printf("Texture is ok!");
    		width  = surface->w;
    		height = surface->h;
    	}
     
    	SDL_SetAlpha(surface, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
     
        // get the number of channels in the SDL surface
        nOfColors = surface->format->BytesPerPixel;
        if (nOfColors == 4)     // contains an alpha channel
        {
    		if (surface->format->Rmask == 0x000000ff)
    			texture_format = GL_RGBA;
            else
    			texture_format = GL_BGRA;
        } 
    	else if (nOfColors == 3)     // no alpha channel
    	{
    		if (surface->format->Rmask == 0x000000ff)
    			texture_format = GL_RGB;
    		else
    			texture_format = GL_BGR;
        } 
    	else 
    	{
    		printf("warning: the image is not truecolor..  this will probably break\n");
            // this error should not go unhandled
        }
     
    	// Have OpenGL generate a texture object handle for us
    	glGenTextures( 1, &amp;texture );
     
    	// Bind the texture object
    	glBindTexture( GL_TEXTURE_2D, texture );
     
    	// 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, nOfColors, surface->w, surface->h, 0,
                          texture_format, GL_UNSIGNED_BYTE, surface->pixels );
     
    	spriteStruct sprite;
     
    	sprite.spriteClip.h = testSurface->h;
    	sprite.spriteClip.w = testSurface->w;
    	sprite.spriteClip.x = 0;
    	sprite.spriteClip.y = 0;
     
    	sprite.spriteTexture = texture;
     
    	// Free the SDL_Surface only if it was successfully created
    	if (surface)  
    		SDL_FreeSurface(surface);
    	if (testSurface)
    		SDL_FreeSurface(testSurface);
     
    	return sprite;
    }

    - Should point out I am using a custom structure which hold both the texture and the sprite rectangle (just for collision stuff) - could this be the problem? - Again though, without blending all works fine.

    Finally textures are rendered as follows

    Code :
     
    int cGraphics::apply_texture(int x, int y, spriteStruct *sprite, SDL_Rect* clip)
    {
     
    	glBindTexture( GL_TEXTURE_2D, sprite->spriteTexture );
     
    	GLfloat textureWidth; GLfloat textureHeight;
     
    	float spriteWidth = sprite->spriteClip.w;
    	float spriteHeight = sprite->spriteClip.h;
     
    	glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &amp;textureWidth);
    	glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &amp;textureHeight);
     
    	float fractionalWidth = spriteWidth/textureWidth;
    	float fractionalHeight = spriteHeight/textureHeight;
     
    	x = float(x);
    	y = float(y);
     
    	glBegin( GL_QUADS );
    		//Bottom-left vertex (corner)
    		glTexCoord2f( 0.f, 0.f );
    		glVertex3f( x, y, 0.f );
     
    		//Bottom-right vertex (corner)
    		glTexCoord2f( fractionalWidth, 0.f );
    		glVertex3f( x+spriteWidth, y, 0.f );
     
    		//Top-right vertex (corner)
    		glTexCoord2f( fractionalWidth, fractionalHeight );
    		glVertex3f( x+spriteWidth, y+spriteHeight, 0.f );
     
    		//Top-left vertex (corner)
    		glTexCoord2f( 0.f, fractionalHeight  );
    		glVertex3f( x, y+spriteHeight, 0.f );
    	glEnd();
     
    	return 0;
    }

    and the buffers swapped:

    Code :
    int cGraphics::show()
    {
    	SDL_GL_SwapBuffers();
           return 0;
    }

    Apologies for so much messy code - hard to keep it tidy with so much mucking about going on...

    Thanks a lot.

  4. #4
    Senior Member Regular Contributor
    Join Date
    Oct 2010
    Location
    France
    Posts
    458

    Re: glBlendFunc() problem

    This line is wrong:

    glClearColor( 255.0f, 0.0f, 0.0f, 0.0f );

    Values must be between 0 (no intensity) and 1 (full intensity). Even if I think this is not the source of your problem, you might have some things similar to this in some other places in your program that could cause this.

    Other parts look ok.

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2011
    Posts
    5

    Re: glBlendFunc() problem

    Hi, thanks for your help, hadn't noticed that.

    Turns out the problem was the way I was returning an SDL surface from a seperate function - this was denying me access to alter the pixel info for some reason, so things weren't doing what I thought they were...

    Cheers!

Similar Threads

  1. glBlendFunc problem
    By Vincent22 in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 04-10-2012, 01:24 PM
  2. Problem with transparency - glBlendFunc()
    By lordmonkey in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 12-23-2010, 11:36 AM
  3. Problem with glBlendFunc!!
    By jamievicary in forum OpenGL: Basic Coding
    Replies: 10
    Last Post: 08-18-2008, 01:11 PM
  4. glBlendFunc problem
    By darkrappey in forum OpenGL: Basic Coding
    Replies: 5
    Last Post: 12-03-2006, 06:45 PM
  5. problem with glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE)
    By Hance in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 11-28-2001, 06:43 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean