Here's my entire sprite loading function. I can make no claims as to the quality of this code.
EDIT: My code broke the forums, it was too long. Changed the conversion part to 2 lines.
EDIT 2: Finally unbroke the forums. Had way too many huge lines. Had to make them all 2 or even 3 lines. Be on the look out for compiler errors if you are copy pasting, although I think it should be okay.
bool bstSprite::loadImg(char *filename, maskflags flags ) { int tempPosNew; int tempPosOld; //Use SDL_Image to load our picture SDL_Surface *sdl_data; sdl_data = IMG_Load(filename); if(!sdl_data) { //Problem loading return false; } //Convert our surface to a true color RGBA surface for easy processing //This byte swapping thing is untested, but in theory, if this compiles on a system //that uses big endian, it'll still show pictures correctly. if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, SDL_Swap32(0x000000FF), SDL_Swap32(0x0000FF00), SDL_Swap32(0x00FF0000), SDL_Swap32(0xFF000000), 0, 255}; sdl_data = SDL_ConvertSurface(sdl_data, &format, SDL_SWSURFACE); } else { SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255}; sdl_data = SDL_ConvertSurface(sdl_data, &format, SDL_SWSURFACE); } //Now we use this sdl_data to make an array of our own data, in order to modify it //to our wishes. First, we need to know what size to make it (has to be a power of 2) //Get and save our dimensions width = (float)sdl_data->w; height = (float)sdl_data->h; trueWidth = 2; trueHeight = 2; //Stop at the first power of 2 that's equal to or greater than the width/height while(trueWidth < width) trueWidth *= 2; while(trueHeight < height) trueHeight *= 2; //Check our width and height and make sure they don't exceed the max texure size int maxsize; glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxsize ); if(trueWidth > maxsize || trueHeight > maxsize) { //Our picture is too big for our user's system return false; } //Now create the "real" texture. Basically the original texture but with the padded pixels SDL_LockSurface( sdl_data ); rgbaByte *rBP = new rgbaByte[(int)(trueWidth * trueHeight)]; rgbaByte temp; //Get the top left pixel if we are in TOP_LEFT mask mode rgbaByte invis; if(flags == TOP_LEFT) { SDL_GetRGBA(((Uint32 *)sdl_data->pixels)[0], (SDL_PixelFormat *)sdl_data->format, &invis.red, &invis.green, &invis.blue, &invis.alpha); } for(int y = 0; y < trueHeight; y++) { for(int x = 0; x < trueWidth; x++) { tempPosNew = (int)(y*trueWidth + x); tempPosOld = (int)(y*width + x); if(y < height && x < width) { //Get pixel data from the SDL surface SDL_GetRGBA(((Uint32 *)sdl_data->pixels)[tempPosOld], (SDL_PixelFormat *)sdl_data->format, &temp.red, &temp.green, &temp.blue, &temp.alpha); rBP[tempPosNew].red = temp.red; rBP[tempPosNew].green = temp.green; rBP[tempPosNew].blue = temp.blue; //If we are in top left mode, see if we have an invisible pixel or not if(flags == TOP_LEFT && temp.red == invis.red && temp.blue == invis.blue && temp.green == invis.green) { rBP[tempPosNew].alpha = 0; } else { rBP[tempPosNew].alpha = temp.alpha; } } else { //Put in a padded pixel rBP[tempPosNew].red = 0; rBP[tempPosNew].green = 0; rBP[tempPosNew].blue = 0; rBP[tempPosNew].alpha = 0; } } } SDL_UnlockSurface( sdl_data ); SDL_FreeSurface( sdl_data ); //Now, just create our surface! glGenTextures(1, &texSprite); glBindTexture(GL_TEXTURE_2D, texSprite); glTexImage2D(GL_TEXTURE_2D, 0, 4, (GLsizei)trueWidth, (GLsizei)trueHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, rBP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); //Check for OpenGL errors, if there are any, return failure. GLenum err = glGetError(); if(err != GL_NO_ERROR) { //Clear all the other errors out, then return failure while(glGetError() != GL_NO_ERROR); return false; } delete[] rBP; return true;}