//To create a blank texture of the given size uint32_t BlankTexture(int width, int height) { /*...*/ SDL_Surface* surface = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); SDL_FillRect(surface, 0, SDL_MapRGBA(surface->format, 0, 0, 0, 0); SDL_SetAlpha(surface, SDL_SRCALPHA, 0); /*...*/ }And, of course, I needed to create something that would let me actually clip a texture, otherwise there would be no real use for obtaining a new blank surface. It automatically generates a new blank surface, so I should probably change things around so I can just directly merge portions of textures with others without the middle step. Oh well.
//To clip a texture uint32_t ClipTexture(uint32_t textureid, int x, int y, int w, int h) { /*...*/ Rect clip = {x, y, w, h}; SDL_Surface* source = textures[textureid].surface; SDL_SetAlpha(source, 0, 0); SDL_Surface* clipped = SDL_CreateRGBSurface(SDL_HWSURFACE, w, h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); SDL_FillRect(clipped, 0, SDL_MapRGBA(clipped->format, 0, 0, 0, 0)); SDL_SetAlpha(clipped, SDL_SRCALPHA, 0); SDL_BlitSurface(source, &clip, clipped, 0); SDL_SetAlpha(source, SDL_SRCALPHA, 0); /*...*/ }Things all went downhill when I tried to re-implement what I thought would simply be the same functionality in my generic DrawTexture() function - I would just need to copy the same SDL_SetAlpha() calls, ignoring the stuff in the middle that automatically generated a new SDL_Surface*, right?
Weeeeell, I'm really terrible at this alpha blending stuff, so I didn't actually do it right for the longest time. It turns out I don't want to be setting the source to be opaque if I'm drawing it to the screen - only if I'm drawing to another surface.
//Draws a texture onto either a texture or the screen void DrawTexture(uint32_t textureid, int x, int y, Rect* srcclip, uint32_t desttexture = 0) { SDL_Surface* destsurface = 0; if(!dest) destsurface = screen->GetSurface(); else { destsurface = textures[desttexture].surface; SDL_SetAlpha(textures[textureid].surface, 0, 0); //Only SetAlpha if drawing to another texture } //^This call used to be outside the conditional right before the SDL_BlitSurface() call Rect offset = {x, y, 1337, 9001}; SDL_SetAlpha(destsurface, SDL_SRCALPHA, 0); SDL_BlitSurface(textures[textureid].surface, clip, destsurface, &offset); SDL_SetAlpha(textures[textureid].surface, SDL_SRCALPHA, 0); //Aaaaaand reset when you're done }I'd been staring at my code wondering why I was just getting white boxes every time I tried drawing things onto other textures; I was especially confused because ClipTexture() worked perfectly fine, and I thought I was doing the same exact thing. Then I tried this, and it worked. At least, I'm pretty sure it works. I haven't tested every scenario, but it certainly does what it wasn't doing before. If you see anything screwed up, I would really appreciate it being fixed ^_^
Lesson learned? Read documentation.