[SDL] SDL_Surface -> OpenGL texture only works with RGBA?

Johannes Bauer dfnsonfsduifb at gmx.de
Fri Dec 7 05:01:32 PST 2007


Hello list,

I've recently updated a routine of mine which converts SDL_Surfaces to
OpenGL Textures - so that it could also process RGB surfaces
(previously, all of them where RGBA which is a waste when I don't need
an alpha channel). However I noticed that surfaces which are RGB are all
defective (distorted, looking like parts of unallocated memory are
rendered) - the RGBA texture conversion works fine, however. Could you
maybe take a look at my code? It should be pretty self-explanatory:

Thank you in advance,
Greetings,
Johannes

--------------- Code ------------------------------------

GLuint Renderer::Convert_Texture(SDL_Surface *Image, bool Tileable, bool
MipMaps, bool TextureFiltering) {
   EXCEPTIONASSERTION((Image->format->BytesPerPixel == 3) ||
(Image->format->BytesPerPixel == 4), "Only RGB and RGBA surfaces are
supported.");

   int Texture_Size = Image->w * Image->h * Image->format->BytesPerPixel;
   EXCEPTIONASSERTION(Texture_Size > 0, "Texture size <= 0");

   GLubyte *Data = new GLubyte[Texture_Size];

   // Traverse through surface and grab the pixels
   int Pos = 0;
   bool Alpha = (Image->format->BytesPerPixel == 4);
   for (int y = Image->h - 1; y >= 0; y--) {
      for (int x = 0; x < Image->w; x++) {
         Uint8 R, G, B, A;

         Uint32 Color = SDLOps::GetPixel(Image, x, y);

         if (!Alpha) {
            SDL_GetRGB(Color, Image->format, &R, &G, &B);
         } else {
            SDL_GetRGBA(Color, Image->format, &R, &G, &B, &A);
         }

         Data[Pos++] = R;
         Data[Pos++] = G;
         Data[Pos++] = B;
         if (Alpha) Data[Pos++] = A;
      }
   }

   GLuint Texture;
   int Texture_Type = Alpha ? GL_RGBA : GL_RGB;
   glGenTextures(1, &Texture);            // Generate texture ID
   glBindTexture(GL_TEXTURE_2D, Texture);

   glTexImage2D(GL_TEXTURE_2D, 0, Texture_Type, Image->w, Image->h, 0,
Texture_Type, GL_UNSIGNED_BYTE, Data);
   int Filter_Minify, Filter_Magnification;
   if (TextureFiltering) {
      Filter_Minify = MipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
      Filter_Magnification = GL_LINEAR;
   } else {
      Filter_Minify = MipMaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
      Filter_Magnification = GL_NEAREST;
   }
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter_Minify);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
Filter_Magnification);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, Tileable ?
GL_REPEAT : GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, Tileable ?
GL_REPEAT : GL_CLAMP);
   if (MipMaps) {
      gluBuild2DMipmaps(GL_TEXTURE_2D, Texture_Type, Image->w, Image->h,
Texture_Type, GL_UNSIGNED_BYTE, Data);
   }

   delete[] Data;
   return Texture;
}





More information about the SDL mailing list