   OpenGL / SDL transparency and Colorkeying problem
  I am working on a simple program to draw spaceships onto a scene.The spaceships are stored in bmp files with black colorkeys. Here is my drawing function:void Ship::show(int whichTexture){    glLoadIdentity();    glTranslatef(x, y, 0);  glEnable(GL_BLEND);    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);    glBindTexture(GL_TEXTURE_2D, texture[whichTexture]);  glBegin( GL_QUADS );   glTexCoord2i(0, 0);  glVertex3f( 0, 0, 0 );   // upper left   glTexCoord2i(1, 0);  glVertex3f( w, 0, 0 );   // upper right   glTexCoord2i(1, 1);  glVertex3f( w, h, 0 );   // bottom right   glTexCoord2i(0, 1);  glVertex3f( 0, h, 0 );   // bottom left    glEnd();   glDisable(GL_BLEND);   glLoadIdentity();}Issue:When I render using: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)Then the ships are displayed without the black area but the ships are also partly transparent.I have a function that is supposed to replace the black pixels with transparent alpha pixels and that seems to have absolutely no effect on this issue.  I can comment the whole section out and it works the same.Pixel replacement function:ship1 = load_image("Federation Eagle Cruiser.bmp");   if( ship1 != NULL )  { // // Loop through every pixel in the SDL Surface  // check its color // if it is true back, set it to transparent. //    int i, j; for( i = 0; i < ship1->w; i++ ) {for (j = 0; j < ship1->h; j++){    Uint8 r;    Uint8 g;    Uint8 b;    Uint8 a;    SDL_LockSurface(ship1);    Uint32 onePixel = getpixel(ship1, i, j);    SDL_UnlockSurface(ship1);    SDL_GetRGBA(onePixel, ship1->format, &r, &g, &b, &a);  // does our rgb match color key of 0,0,0 black?    if (r ==0 && g == 0 && b == 0)    {  // if so, then set alpha to transparent  a = 0;  Uint32 newPixel = SDL_MapRGBA(ship1->format, 0, 0, 0, 0);  SDL_LockSurface(ship1);  putpixel(ship1, i, j, newPixel);SDL_UnlockSurface(ship1);    }} } } // <end if ship!=nullWhat I want is a fully opaque ship with a fully transparent black background.  How can I modify this code to achieve that result?for reference, here is my get/put pixel function:Uint32 getpixel(SDL_Surface *surface, int x, int y){    int bpp = surface->format->BytesPerPixel;    /* Here p is the address to the pixel we want to retrieve */    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;    switch(bpp) {    case 1:   return *p;   break;    case 2:   return *(Uint16 *)p;   break;    case 3:   if(SDL_BYTEORDER == SDL_BIG_ENDIAN)  return p[0] << 16 | p[1] << 8 | p[2];   else  return p[0] | p[1] << 8 | p[2] << 16;   break;    case 4:   return *(Uint32 *)p;   break;    default:   return 0;  /* shouldn't happen, but avoids warnings */    }}void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel){    int bpp = surface->format->BytesPerPixel;    /* Here p is the address to the pixel we want to set */    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;    switch(bpp) {    case 1:   *p = pixel;   break;    case 2:   *(Uint16 *)p = pixel;   break;    case 3:   if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {  p[0] = (pixel >> 16) & 0xff;  p[1] = (pixel >> 8) & 0xff;  p[2] = pixel & 0xff;   } else {  p[0] = pixel & 0xff;  p[1] = (pixel >> 8) & 0xff;  p[2] = (pixel >> 16) & 0xff;   }   break;    case 4:   *(Uint32 *)p = pixel;   break;    }}SOMETHING is wrong with my pixel replacement, I am sure.  But I also think there is something wrong with my GL blending.   
  check out SDL_SetColorKey function. It does what you are looking for   ;Quote:Original post by Juanxocheck out SDL_SetColorKey function. It does what you are looking forI know how to use this function.  The problem is that I am not blitting the texture anywhere.  I am mapping it to an OpenGL quad.  So I believe that the SDL_ColorKey won't affect the base image in memory; it will just set a color key when it Blits.I am trying to alter the pixels on the surface itself before I map the surface to a texture.   ;  If you set the colour key of an SDL surface and then use SDL_DisplayFormatAlpha() or SDL_ConvertSurface(), it should turn the colour key into a true alpha channel. That is, if I recall, the quick and easy way to do it.Also, here:SDL_LockSurface(ship1);Uint32 onePixel = getpixel(ship1, i, j);SDL_UnlockSurface(ship1);You really should be doing those calls to SDL_LockSurface() and SDL_UnlockSurface outside the loop; locking and unlocking a surface can be expensive because, if it's in hardware memory, it has to be copied to software memory first.Happy coding!   ;  You could always just blit to a temporary surface using the colorkey. Try putting in a glColor4f(1.0, 1.0, 1.0, 1.0); call before you draw the ship, to make sure that's not an issue (might cause the transparency?).(Unrelatedly it's probably a better idea to lock / unlock the surface once outside the for loop, instead of for every pixel.)Would also be helpful to see your sdl -> ogl texture loading function, and load_image().   ;  i think you are using SDL windows, so you can do this for create OGL textures with SDL:   int red = 0, blue = 0, green = 0;SDL_Surface* base_image = IMG_Load("MyImage.png");SDL_SetColorKey(base_image, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB(base_image->format, red, blue, green));SDL_Surface* final_image = SDL_DisplayFormatAlpha(base_image);SDL_FreeSurface(base_image);unsigned int id(0);glGenTextures(1, &id);glBindTexture(GL_TEXTURE_2D, id);   //... Whatever parameters you wantglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);// Create Texture from imageglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, final_image->w, final_image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, final_image->pixels);return id;;Quote:Original post by Juanxoi think you are using SDL windows, so you can do this for create OGL textures with SDL:*** Source Snippet Removed ***Juanxo, thank you.  That is actually exactly what I have done.However, glBlendFunc is killing me.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)This BlendFunc gives me a texture with good transparency.  However, the colors are all messed up. The colors are too heavily saturated.  When my ship should be blue it is instead brown.glBlendFunc(GL_SRC_ALPHA, GL_ONE);This seems to chop alpha in half.   ;  i had some problems like yours. And i solved them trying different formats in this function:glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, final_image->w, final_image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, final_image->pixels);You need to change GL_RGBA parameters: try for example GL_RGBA for the first and GL_BGRA for the second. It depends if your system it's big or little endian...you know   ;Quote:Original post by Juanxoi had some problems like yours. And i solved them trying different formats in this function:glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, final_image->w, final_image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, final_image->pixels);You need to change GL_RGBA parameters: try for example GL_RGBA for the first and GL_BGRA for the second. It depends if your system it's big or little endian...you knowOh man, that was it.  Thank you so much.   