Make texture flash white

In old time games enemies use to blink white when you hit them. Is there a clever way to do this in SDL?
I tried making the SDL_Texture semi-transparent with SDL_SetTextureAlphaMod(texture1, 128); and draw it several times because I was thinking “adding a transparent layer several times will fate to white” but that did nothing.

The next thing I can come up with is scan the texture for non-invisible pixels (with something like this https://stackoverflow.com/questions/47106312/access-pixel-color-from-sdl-texture) and draw a half transparent white point over them with SDL_RenderDrawPoint but that don’t seem clever to me.
I would be awesome if there was a version of SDL_SetTextureColorMod that increased the color of the texture to make it whiter.

Is there a clever way to do this that I have missed?

SDL might not have the required functionality for this. You can generate white versions of your sprites if the performance and memory requirements are okay.

If you go beyond SDL_Renderer to using OpenGL directly or using SDL_gpu, you can either use a shader (best control) or draw the sprite and then immediately draw it again additively with the equivalent of GL_ONE_MINUS_SRC_COLOR (or something along those lines, but taking alpha separately).

I don’t know if you’re using SDL’s standard initialization or if you’re leveraging its OpenGL avenue, but if you’re doing the latter, something I’ve done is draw a textured quad with a specific color over the quad (same coordinates and size) that has my sprite texture mapped onto it.

What I do is to select SDL_BLENDMODE_ADD by calling SDL_SetTextureBlendMode() and then draw the object several times. Because of the automatic clipping this will cause brighter regions of the object to turn white and less bright regions to brighten. It’s not exactly the effect you ask for, but is quite effective in my experience.

1 Like

I think the old games used white masks that were XOR’d onto the screen, then the sprite images were XOR’d after think. I have some working code to mimic the technique but I’m not sure if I’m allowed to post it… I hope it’s useful.

bool Model::Draw(RGB *ColourOverride)
{
if (!IsLoaded) return false;

FACE_MATERIAL_DATA *MatData = TheModel->FaceMaterials;

// we will use vertex arrays, so enable them
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

// set the material shininess factor
float shininess;
shininess = 50.0f;
glMaterialfv(GL_FRONT, GL_SHININESS, &shininess);

// set the vertex and normal buffers
glVertexPointer(3, GL_FLOAT, 0, TheModel->VertexData);
glNormalPointer(GL_FLOAT, 0, TheModel->VertexNormals);

while (MatData != NULL)
{
	//Set Ambient, Diffuse and Specular Material Colours
	if (ColourOverride)
	{
		glMaterialfv(GL_FRONT, GL_AMBIENT, (float *) ColourOverride);
		glMaterialfv(GL_FRONT, GL_DIFFUSE,  (float *) ColourOverride);
		glMaterialfv(GL_FRONT, GL_SPECULAR, (float *) ColourOverride);
	}
	
	if (MatData->TexHandle && !ColourOverride)
	{
		glEnable(GL_TEXTURE_2D);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	  glBindTexture(GL_TEXTURE_2D, (MatData->TexHandle)->GetGLTextureHandle());
    glTexCoordPointer(2, GL_FLOAT, 0, TheModel->MappingCoords);
	}
		
	glDrawElements(GL_TRIANGLES, MatData->NumFacesWithThisMaterial * 3, GL_UNSIGNED_SHORT, MatData->GLFaceData);
  
	if (MatData->TexHandle && !ColourOverride)
	{
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  glDisable(GL_TEXTURE_2D);
	}

	MatData = MatData->Next;
}

 // clear vertex array state

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

return true;

}