Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Khaos Dragon

problem in my color keying code

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

I am adapting the CreateTexture function from the famous gametutorials site to be able to handle both normal images and color
keyed images. The new function which I have so far takes in an additional boolean argument which is true if all black colored pixels
should be keyed out. Otherwise, if it is false, the function should work normally. By the way, it works fine whenever I don't use color keying... I just don't see any transparency when I do use color keying and it looks entirely the same as if I didn't use it all. Here is my function:
void CreateTexture( unsigned int* intPtr, char* filename, bool color_key)
{
    int channels;
    unsigned char * newData;
    SDL_Surface *pBitmap[1];
    pBitmap[0] = IMG_Load( filename );       
    if(pBitmap[0] == NULL)                                
        return;

    glGenTextures(1, intPtr );
    glBindTexture(GL_TEXTURE_2D, *intPtr );
    int width  = pBitmap[0] -> w;
    int height = pBitmap[0] -> h;
    unsigned char * data = (unsigned char *) (pBitmap[0] -> pixels);   

    if( !color_key)
    {
	channels = 3;
	newData = new unsigned char[width*height*3];
     }
    else
    {
	channels = 4;
	newData = new unsigned char[width*height*4];
     }

    int BytesPerPixel = pBitmap[0] -> format -> BytesPerPixel ; 
    for( int i = 0 ; i < (height / 2) ; ++i )
        for( int j = 0 ; j < width * BytesPerPixel; j += BytesPerPixel )
            for(int k = 0; k < BytesPerPixel; ++k)
			{
				unsigned char  temp = data[ (i * width * BytesPerPixel) + j + k];
				data[ (i * width * BytesPerPixel) + j + k]    =  data[ ( (height - i - 1) * width * BytesPerPixel ) + j + k];
				data[ ( (height - i - 1) * width * BytesPerPixel ) + j + k]    = temp;
			}
    for(i = 0; i < (width * height); ++i)
    {
        unsigned char r,g,b;                                               
        Uint32 pixel_value = 0;                                    
        for(int j = BytesPerPixel - 1 ; j >=0; --j)                
        {
            pixel_value = pixel_value << 8;                        
            pixel_value = pixel_value | data[ (i * BytesPerPixel) + j ]; 
        }                                                                 
        SDL_GetRGB(pixel_value, pBitmap[0] -> format, (Uint8 *)&r, (Uint8 *)&g, (Uint8 *)&b);    
        
	newData[(i * channels) + 0] = r;        
        newData[(i * channels) + 1] = g;          
        newData[(i * channels) + 2] = b;    
	if( color_key )
	{
	     if( r == 0 && g == 0 && b == 0 )
		newData[(i * channels) + 3] == 0;
	     else
		newData[(i * channels) + 3] == 255;
	}

        pixel_value = 0;                                           
    }
    
	if( color_key )
		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap[0]->w, pBitmap[0]->h, GL_RGBA, GL_UNSIGNED_BYTE, newData);
	else
		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap[0]->w, pBitmap[0]->h, GL_RGB, GL_UNSIGNED_BYTE, newData);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
    delete [] newData;
    SDL_FreeSurface(pBitmap[0]);                       
}
     
Then in my rendering loop I do this: glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); before I actually enable my texturing and draw my textured polies. But the black colored part of the texture still shows.I have no idea what I could be doing wrong. Any help would greatly be appreciated. [edited by - Khaos Dragon on June 2, 2004 12:10:38 AM] [edited by - Khaos Dragon on June 2, 2004 12:11:30 AM] [edited by - Khaos Dragon on June 2, 2004 12:14:37 AM] [edited by - Khaos Dragon on June 2, 2004 12:16:14 AM]

Share this post


Link to post
Share on other sites
Advertisement
and for reference I am posting the original version of the CreateTexture function. I realize I use an integer pointer instead of an array but it works fine.
Example of how I make a texture.
unsigned int tex_id;
CreateTexture( &tex_id, "picture.bmp", false );

Anyways here is gametutorial''s version:



void CreateTexture(unsigned int textureArray[],char *strFileName,int textureID)
{
SDL_Surface *pBitmap[1];

if( strFileName == NULL ) // Return from the function if no file name was passed in
return ;

// We need to load the texture data, so we use a cool function that SDL offers.

pBitmap[0] = SDL_LoadBMP(strFileName); // Load the bitmap and store the data

if(pBitmap[0] == NULL) // If we can''t load the file, quit!
{
cerr << " Failed loading " << strFileName << " : " << SDL_GetError() << endl;
Quit(0);
}

// Now that we have the texture data, we need to register our texture with OpenGL
// To do this we need to call glGenTextures(). The 1 for the first parameter is
// how many texture we want to register this time (we could do a bunch in a row).
// The second parameter is the array index that will hold the reference to this texture.

// Generate a texture with the associative texture ID stored in the array
glGenTextures(1, &textureArray[textureID]);

// Now that we have a reference for the texture, we need to bind the texture
// to tell OpenGL this is the reference that we are assigning the bitmap data too.
// The first parameter tells OpenGL we want are using a 2D texture, while the
// second parameter passes in the reference we are going to assign the texture too.
// We will use this function later to tell OpenGL we want to use this texture to texture map.

// Bind the texture to the texture arrays index and init the texture
glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);

// WARNING : GO THROUGH THESE FEW LINES FOR SWAPPING ROWS onLY IF YOU REALLY NEED TO, OR ELSE SKIP
// THE LINES MARKED BELOW. Just take it for granted that these lines of code swap rows in the texture
// as required by us.

// (FROM HERE) -------------------
//
// IMPORTANT : SDL loads Bitmaps differently when compared to the default windows loader. The row 0
// corresponds to the top row and NOT the bottom row. Therefore if we don''t invert the order of the rows,
// then the textures will appear (vertically) inverted.
// Therefore we must reverse the ordering of the rows in the data of the loaded surface ( the member
// ''pixels'' of the structure)

// Rearrange the pixelData

int width = pBitmap[0] -> w;
int height = pBitmap[0] -> h;
unsigned char * data = (unsigned char *) (pBitmap[0] -> pixels); // the pixel data
unsigned char * newData = new unsigned char[width*height*3];
int channels = 3; // R,G,B

int BytesPerPixel = pBitmap[0] -> format -> BytesPerPixel ;

//////////// This is how we swap the rows :
// For half the rows, we swap row ''i'' with row ''height - i -1''. (if we swap all the rows
// like this and not the first half or the last half, then we get the same texture again !
//
// Now these rows are not stored as 2D arrays, instead they are stored as a long 1D array.
// So each row is concatenated after the previous one to make this long array. Our swap
// function swaps one byte at a time and therefore we swap BytesPerPixel (= total bits per pixel)
// bytes succesively.
//
// so the three loops below are :
// for the first half of the rows
// for all the width (which is width of image * BytesPerPixel, where BytesPerPixel = total bits per pixel).
// (Here, for each pixel, we have to increment j by total bits per pixel (to get to next pixel to swap))
// for(each byte in this pixel i.e k = 0 to BytesPerPixel - 1, i.e BytesPerPixel bytes.
// swap the byte with the corresponding byte in the ''height -i -1''th row (''i''th row from bottom)
for( int i = 0 ; i < (height / 2) ; ++i )
for( int j = 0 ; j < width * BytesPerPixel; j += BytesPerPixel )
for(int k = 0; k < BytesPerPixel; ++k)
swap( data[ (i * width * BytesPerPixel) + j + k], data[ ( (height - i - 1) * width * BytesPerPixel ) + j + k]);

//
(TO HERE) -------------------

// the following lines extract R,G and B values from any bitmap

for(int i = 0; i < (width * height); ++i)
{
byte r,g,b; // R,G and B that we will put into pImage

Uint32 pixel_value = 0; // 32 bit unsigned int (as dictated by SDL)

// the following loop extracts the pixel (however wide it is 8,16,24 or 32) and
// creates a long with all these bytes taken together.

for(int j = BytesPerPixel - 1 ; j >=0; --j) // for each byte in the pixel (from the right)
{
pixel_value = pixel_value << 8; // left shift pixel value by 8 bits
pixel_value = pixel_value | data[ (i * BytesPerPixel) + j ]; // then make the last 8 bits of pixel value =
} // the byte that we extract from pBitmap''s data

SDL_GetRGB(pixel_value, pBitmap[0] -> format, (Uint8 *)&r, (Uint8 *)&g, (Uint8 *)&b); // here we get r,g,b from pixel_value which is stored in the form specified by pBitmap->format

newData[(i * channels) + 0] = r; // in our tImage classes we store r first
newData[(i * channels) + 1] = g; // then g
newData[(i * channels) + 2] = b; // and finally b (for bmps - three channels only)

pixel_value = 0; // reset pixel , else we get incorrect values of r,g,b
}


// Now comes the important part, we actually pass in all the data from the bitmap to
// create the texture. Here is what the parameters mean in gluBuild2DMipmaps():
// (We want a 2D texture, 3 channels (RGB), bitmap width, bitmap height, It''s an RGB format,
// the data is stored as unsigned bytes, and the actuall pixel data);

// What is a Mip map? Mip maps are a bunch of scaled pictures from the original. This makes
// it look better when we are near and farther away from the texture map. It chooses the
// best looking scaled size depending on where the camera is according to the texture map.
// Otherwise, if we didn''t use mip maps, it would scale the original UP and down which would
// look not so good when we got far away or up close, it would look pixelated.

// Build Mipmaps (builds different versions of the picture for distances - looks better)

// Build Mipmaps (builds different versions of the picture for distances - looks better)
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap[0]->w, pBitmap[0]->h, GL_RGB, GL_UNSIGNED_BYTE, newData);

// Lastly, we need to tell OpenGL the quality of our texture map. GL_LINEAR_MIPMAP_LINEAR
// is the smoothest. GL_LINEAR_MIPMAP_NEAREST is faster than GL_LINEAR_MIPMAP_LINEAR,
// but looks blochy and pixilated. Good for slower computers though. Read more about
// the MIN and MAG filters at the bottom of main.cpp
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);

// Now we need to free the bitmap data that we loaded since openGL stored it as a texture
delete [] newData;

SDL_FreeSurface(pBitmap[0]); // Free the texture data we dont need it anymore
}

Share this post


Link to post
Share on other sites
perhaps you should use a different color then black for the color key unless you dont want to show black in your textures.
The most popular color to set as the color key is magenta I think it is called. It is r = 255, g = 0, b = 255 I think....the bright pink color


"A soldier is a part of the 1% of the population that keeps the other 99% free" - Lt. Colonel Todd, 1/38th Infantry, Ft. Benning, GA

Share this post


Link to post
Share on other sites
quote:
Original post by Raduprv
Try to use Alpha Testing


I tried glEnable(GL_ALPHA_TEST);glAlphaFunc(GL_GREATER,0.0f);
before my rendering and alas it had no effect.

It doesn''t make sense to me why this isn''t working.

Share this post


Link to post
Share on other sites
I am not sure what that function does exactly. Anyway, you might want to icnrease the Alpha Test value from 0.0 to 0.1
0.0 lets everything pass.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!