Setting all non transparent pixels in a surface or texture to white?

What’s the most efficient way to turn a multicolor surface or texture into a black and white one? Basically any non black or transparent pixel should be set to white.

Basically any non black or transparent pixel should be set to white.

To be clear, is this really what you wanted? If so, my avatar…

… would look like this…

Which is kind of a cool effect, but did you instead want to make it grayscale (which is what a “black and white” movie is more like)? So it looks like this instead…

The algorithm changes a little, but both are simple bits of processing on an SDL_Surface.

Neither of those, this is what I’m trying to achieve:

Basically I want all non background pixels to be set to white, I change the background in your avatar to black to show the final effect I want. And I want to do it in hardware, so no reading across the bus. I could precalculate it on load time and fairly easily do it in software, but I’d like to do it on the GPU.

Oh, I misunderstood what you meant, sorry.

If you’re using SDL_RenderCopy or SDL_RenderCopyEx with an SDL_Texture, you might be able to force this with modulation, but I don’t know if this actually works in practice:

(EDIT: this doesn’t work.)

// Multiply red, green, and blue by 255, 
// effectively making every pixel white.
SDL_SetTextureColorMod(myTexture, 255, 255, 255);

// Multiply alpha by 255, so completely transparent pixels
// stay transparent (0*255=0), and everything else becomes
// fully opaque.
SDL_SetTextureAlphaMod(myTexture, 255);

…assuming this will saturate to full intensity if the multiplication against 255 becomes > 255, then the SDL_RenderCopy will give you the result you want, with one exception: if any of R,G, or B is zero, you won’t get a full white pixel on that one.

I’d have to think this through some more. This is very easy with a pixel shader, but the SDL_render options are pretty limited here.

Actually this doesn’t multiply the channels by 255, it multiplies them with 1. So 255, 255, 255 will just get you your original texture. So that doesn’t work :frowning:

I found something on the wiki called “SDL_TEXTUREMODULATE_COLOR” which is an enum, but I can’t find anything else about how or where to use it, anyone?

To followup, Sam just added custom blend modes, which might be useful here:

I saw that, I’m going to play around with it as soon as I get a chance! He actually filled one of my other feature requests for subtractive blending, SDL might finally do everything I need it to! :smiley:

1 Like

Having some trouble implementing a custom blend mode, namely subtractive. Here’s the relevant code:

Creating my renderer:
SDL_Renderer* main_renderer = NULL;
main_renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

Setting up the blend mode as per Sams example:
SDL_BlendMode SubBlendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT, SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT);
SDL_SetTextureBlendMode(tempbuffer, SubBlendMode);
SDL_SetTextureAlphaMod(tempbuffer, 255);

And rendering it:
SDL_RenderCopy(main_renderer, tempbuffer, &srcRect, &dstRect);

But it is rendering with no blending at all. Should be noted that the “tempbuffer” texture has no alpha channel, I want to subtract the RGB values from the destination RGB values. Not exactly sure who to set up the blend mode to do that.
The operation I want is:
dstR = dstR - (srcR * srcTextureAlphaMod)
dstG = dstG - (srcG * srcTextureAlphaMod)
dstB = dstB - (srcB * srcTextureAlphaMod)

In fact, it seems the default accelerated renderer doesn’t support this as no matter what I set the blend mode to it doesn’t change the outcome.
[edit]If I change the blendoperation to ADD it works fine, but not subtract. So, help! :slight_smile:

Are you on Windows and using the direct3d renderer? It seems the subtractive modes are not yet implemented in SDL for this renderer. Pretty sure Direct3D 9 can do that, but perhaps there were other issues. You could try the opengl renderer.

Yes I’m on Windows. I just use SDL_RENDERER_ACCELERATED, assuming SDL would automatically select the best one? How do you force a certain renderer? Didn’t find anything on the wiki.

It does. Direct3D almost always got better drivers on Windows.

You can tell SDL to select a specific renderer by looking at the available ones with SDL_GetNumRenderDrivers and SDL_GetRenderDriverInfo. If it lists one that is named opengl, use the index of it in the SDL_CreateRenderer call.

Alternatively, you can use SDL’s hint system. Set the environment variable SDL_RENDER_DRIVER to opengl and SDL will choose this one in the automatic render driver selection, if it is available. It is just a hint, it might get ignored. Check the name of the created renderer to make sure.

Just in case you’re not familiar with environment variables: You can simply open cmd.exe and set it there. The command set manages the environment variables for that console.

set SDL_RENDER_DRIVER=opengl
mysdlprogram.exe

Oh, I just noticed that the direct3d11 renderer supports the subtractive blend mode. However, it looks like this driver does not get built with the default config. (Guessing not enough testing yet? Seemed to work decently the few times I tried it.) If you build SDL yourself, you have to define SDL_VIDEO_RENDER_D3D11=1 to enable it. If you got one of the nightly builds it might be enabled in there. I’ll check later. Edit: The visualstudio build from https://buildbot.libsdl.org doesn’t have it.

Note that the direct3d11 renderer will be selected after the direct3d renderer in the automatic selection. You have to use one of the methods described above to select it.

Got it sorted out. OpenGL supports the subtractive blending I need. I’m sticking to OpenGL for compatibility reasons, there may be more than Windows versions in my future. The Wiki really needs to be updated to all the new functionality.
Here’s the relevant parts of my code, hope it helps someone until the Wiki is updated:

// Enumerate all available renderers on the system
int numRenderers = SDL_GetNumRenderDrivers();
if (numRenderers < 0)
{
	cout << "Unable to enumerate renderers: " << SDL_GetError() << endl;
	SDL_Quit();
	return 0;
}

// Iterate through them and select the desired one based on the name string. Set the index value to -1 to let SDL autoselect in case our renderer doesn't exist (TODO: error checking)
SDL_RendererInfo renderInfo;
int rendIndex = -1;
for (int i = 0; i < numRenderers; ++i)
{
	SDL_GetRenderDriverInfo(i, &renderInfo);
	if (strcmp(renderInfo.name, "opengl") == 0)
	{
		rendIndex = i;
		break;
	}
}

// Create our renderer with the selected index, or use the default -1 if our desired one was not found
SDL_Renderer* main_renderer = NULL;
main_renderer = SDL_CreateRenderer(window, rendIndex, SDL_RENDERER_ACCELERATED);
if (main_renderer == NULL)
{
	cout << "Unable to create renderer: " << SDL_GetError() << endl;
	SDL_Quit();
	return 0;
}

Great. I’m sure the wiki will get updated once 2.0.6 is finalized.

For reference, here is what blend modes the renderers report as supported on my systems with the current tip. This may change before the 2.0.6 release. OpenGL should also be able to do more.

Linux
Intel GMA 950 on Linux
SDL2 e3797888c6f1 2017-08-20
There are 4 renderers available.
-- 0 --
       Name: opengl
  Texlimits: 2048x2048
      Flags: (0x0000000a) hardware targettexture
Texturefmts: 5
             SDL_PIXELFORMAT_ARGB8888      0x16362004   372645892
             SDL_PIXELFORMAT_YV12          0x32315659   842094169
             SDL_PIXELFORMAT_IYUV          0x56555949  1448433993
             SDL_PIXELFORMAT_NV12          0x3231564e   842094158
             SDL_PIXELFORMAT_NV21          0x3132564e   825382478
Blendmodes: NONE, BLEND, ADD, MOD, and 29996 custom blendmodes.
            Color Op       Alpha Op            Modes
             ADD            ADD                  9996
             SUBTRACT       SUBTRACT            10000
             REV_SUBTRACT   REV_SUBTRACT        10000
             MINIMUM        MINIMUM                 0
             MAXIMUM        MAXIMUM                 0
             ADD            SUBTRACT                0
             ADD            REV_SUBTRACT            0
             ADD            MINIMUM                 0
             ADD            MAXIMUM                 0
             SUBTRACT       ADD                     0
             SUBTRACT       REV_SUBTRACT            0
             SUBTRACT       MINIMUM                 0
             SUBTRACT       MAXIMUM                 0
             REV_SUBTRACT   ADD                     0
             REV_SUBTRACT   SUBTRACT                0
             REV_SUBTRACT   MINIMUM                 0
             REV_SUBTRACT   MAXIMUM                 0
             MINIMUM        ADD                     0
             MINIMUM        SUBTRACT                0
             MINIMUM        REV_SUBTRACT            0
             MINIMUM        MAXIMUM                 0
             MAXIMUM        ADD                     0
             MAXIMUM        SUBTRACT                0
             MAXIMUM        REV_SUBTRACT            0
             MAXIMUM        MINIMUM                 0

-- 1 --
       Name: opengles2
  Texlimits: 2048x2048
      Flags: (0x0000000a) hardware targettexture
Texturefmts: 8
             SDL_PIXELFORMAT_ARGB8888      0x16362004   372645892
             SDL_PIXELFORMAT_ABGR8888      0x16762004   376840196
             SDL_PIXELFORMAT_RGB888        0x16161804   370546692
             SDL_PIXELFORMAT_BGR888        0x16561804   374740996
             SDL_PIXELFORMAT_YV12          0x32315659   842094169
             SDL_PIXELFORMAT_IYUV          0x56555949  1448433993
             SDL_PIXELFORMAT_NV12          0x3231564e   842094158
             SDL_PIXELFORMAT_NV21          0x3132564e   825382478
Blendmodes: NONE, BLEND, ADD, MOD, and 89996 custom blendmodes.
            Color Op       Alpha Op            Modes
             ADD            ADD                  9996
             SUBTRACT       SUBTRACT            10000
             REV_SUBTRACT   REV_SUBTRACT        10000
             MINIMUM        MINIMUM                 0
             MAXIMUM        MAXIMUM                 0
             ADD            SUBTRACT            10000
             ADD            REV_SUBTRACT        10000
             ADD            MINIMUM                 0
             ADD            MAXIMUM                 0
             SUBTRACT       ADD                 10000
             SUBTRACT       REV_SUBTRACT        10000
             SUBTRACT       MINIMUM                 0
             SUBTRACT       MAXIMUM                 0
             REV_SUBTRACT   ADD                 10000
             REV_SUBTRACT   SUBTRACT            10000
             REV_SUBTRACT   MINIMUM                 0
             REV_SUBTRACT   MAXIMUM                 0
             MINIMUM        ADD                     0
             MINIMUM        SUBTRACT                0
             MINIMUM        REV_SUBTRACT            0
             MINIMUM        MAXIMUM                 0
             MAXIMUM        ADD                     0
             MAXIMUM        SUBTRACT                0
             MAXIMUM        REV_SUBTRACT            0
             MAXIMUM        MINIMUM                 0

-- 2 --
       Name: opengles
  Texlimits: 2048x2048
      Flags: (0x0000000a) hardware targettexture
Texturefmts: 1
             SDL_PIXELFORMAT_ABGR8888      0x16762004   376840196
Blendmodes: NONE, BLEND, ADD, MOD, and 89996 custom blendmodes.
            Color Op       Alpha Op            Modes
             ADD            ADD                  9996
             SUBTRACT       SUBTRACT            10000
             REV_SUBTRACT   REV_SUBTRACT        10000
             MINIMUM        MINIMUM                 0
             MAXIMUM        MAXIMUM                 0
             ADD            SUBTRACT            10000
             ADD            REV_SUBTRACT        10000
             ADD            MINIMUM                 0
             ADD            MAXIMUM                 0
             SUBTRACT       ADD                 10000
             SUBTRACT       REV_SUBTRACT        10000
             SUBTRACT       MINIMUM                 0
             SUBTRACT       MAXIMUM                 0
             REV_SUBTRACT   ADD                 10000
             REV_SUBTRACT   SUBTRACT            10000
             REV_SUBTRACT   MINIMUM                 0
             REV_SUBTRACT   MAXIMUM                 0
             MINIMUM        ADD                     0
             MINIMUM        SUBTRACT                0
             MINIMUM        REV_SUBTRACT            0
             MINIMUM        MAXIMUM                 0
             MAXIMUM        ADD                     0
             MAXIMUM        SUBTRACT                0
             MAXIMUM        REV_SUBTRACT            0
             MAXIMUM        MINIMUM                 0

-- 3 --
       Name: software
  Texlimits: 0x0
      Flags: (0x00000009) software targettexture
Texturefmts: 8
             SDL_PIXELFORMAT_ARGB8888      0x16362004   372645892
             SDL_PIXELFORMAT_ABGR8888      0x16762004   376840196
             SDL_PIXELFORMAT_RGBA8888      0x16462004   373694468
             SDL_PIXELFORMAT_BGRA8888      0x16862004   377888772
             SDL_PIXELFORMAT_RGB888        0x16161804   370546692
             SDL_PIXELFORMAT_BGR888        0x16561804   374740996
             SDL_PIXELFORMAT_RGB565        0x15151002   353701890
             SDL_PIXELFORMAT_RGB555        0x15130f02   353570562
Blendmodes: NONE, BLEND, ADD, MOD, and 0 custom blendmodes.
Windows
Intel HD Graphics 400 on Windows
SDL2 e3797888c6f1 2017-08-20
There are 5 renderers available.
-- 0 --
       Name: direct3d
  Texlimits: 8192x8192
      Flags: (0x0000000a) hardware targettexture
Texturefmts: 3
             SDL_PIXELFORMAT_ARGB8888      0x16362004 00372645892
             SDL_PIXELFORMAT_YV12          0x32315659 00842094169
             SDL_PIXELFORMAT_IYUV          0x56555949 01448433993
Blendmodes: NONE, BLEND, ADD, MOD, and 9996 custom blendmodes.
            Color Op       Alpha Op            Modes
             ADD            ADD                  9996
             SUBTRACT       SUBTRACT                0
             REV_SUBTRACT   REV_SUBTRACT            0
             MINIMUM        MINIMUM                 0
             MAXIMUM        MAXIMUM                 0
             ADD            SUBTRACT                0
             ADD            REV_SUBTRACT            0
             ADD            MINIMUM                 0
             ADD            MAXIMUM                 0
             SUBTRACT       ADD                     0
             SUBTRACT       REV_SUBTRACT            0
             SUBTRACT       MINIMUM                 0
             SUBTRACT       MAXIMUM                 0
             REV_SUBTRACT   ADD                     0
             REV_SUBTRACT   SUBTRACT                0
             REV_SUBTRACT   MINIMUM                 0
             REV_SUBTRACT   MAXIMUM                 0
             MINIMUM        ADD                     0
             MINIMUM        SUBTRACT                0
             MINIMUM        REV_SUBTRACT            0
             MINIMUM        MAXIMUM                 0
             MAXIMUM        ADD                     0
             MAXIMUM        SUBTRACT                0
             MAXIMUM        REV_SUBTRACT            0
             MAXIMUM        MINIMUM                 0

-- 1 --
       Name: direct3d11
  Texlimits: 16384x16384
      Flags: (0x0000000a) hardware targettexture
Texturefmts: 4
             SDL_PIXELFORMAT_ARGB8888      0x16362004 00372645892
             SDL_PIXELFORMAT_RGB888        0x16161804 00370546692
             SDL_PIXELFORMAT_YV12          0x32315659 00842094169
             SDL_PIXELFORMAT_IYUV          0x56555949 01448433993
Blendmodes: NONE, BLEND, ADD, MOD, and 249996 custom blendmodes.
            Color Op       Alpha Op            Modes
             ADD            ADD                  9996
             SUBTRACT       SUBTRACT            10000
             REV_SUBTRACT   REV_SUBTRACT        10000
             MINIMUM        MINIMUM             10000
             MAXIMUM        MAXIMUM             10000
             ADD            SUBTRACT            10000
             ADD            REV_SUBTRACT        10000
             ADD            MINIMUM             10000
             ADD            MAXIMUM             10000
             SUBTRACT       ADD                 10000
             SUBTRACT       REV_SUBTRACT        10000
             SUBTRACT       MINIMUM             10000
             SUBTRACT       MAXIMUM             10000
             REV_SUBTRACT   ADD                 10000
             REV_SUBTRACT   SUBTRACT            10000
             REV_SUBTRACT   MINIMUM             10000
             REV_SUBTRACT   MAXIMUM             10000
             MINIMUM        ADD                 10000
             MINIMUM        SUBTRACT            10000
             MINIMUM        REV_SUBTRACT        10000
             MINIMUM        MAXIMUM             10000
             MAXIMUM        ADD                 10000
             MAXIMUM        SUBTRACT            10000
             MAXIMUM        REV_SUBTRACT        10000
             MAXIMUM        MINIMUM             10000

-- 2 --
       Name: opengl
  Texlimits: 16384x16384
      Flags: (0x0000000a) hardware targettexture
Texturefmts: 5
             SDL_PIXELFORMAT_ARGB8888      0x16362004 00372645892
             SDL_PIXELFORMAT_YV12          0x32315659 00842094169
             SDL_PIXELFORMAT_IYUV          0x56555949 01448433993
             SDL_PIXELFORMAT_NV12          0x3231564e 00842094158
             SDL_PIXELFORMAT_NV21          0x3132564e 00825382478
Blendmodes: NONE, BLEND, ADD, MOD, and 29996 custom blendmodes.
            Color Op       Alpha Op            Modes
             ADD            ADD                  9996
             SUBTRACT       SUBTRACT            10000
             REV_SUBTRACT   REV_SUBTRACT        10000
             MINIMUM        MINIMUM                 0
             MAXIMUM        MAXIMUM                 0
             ADD            SUBTRACT                0
             ADD            REV_SUBTRACT            0
             ADD            MINIMUM                 0
             ADD            MAXIMUM                 0
             SUBTRACT       ADD                     0
             SUBTRACT       REV_SUBTRACT            0
             SUBTRACT       MINIMUM                 0
             SUBTRACT       MAXIMUM                 0
             REV_SUBTRACT   ADD                     0
             REV_SUBTRACT   SUBTRACT                0
             REV_SUBTRACT   MINIMUM                 0
             REV_SUBTRACT   MAXIMUM                 0
             MINIMUM        ADD                     0
             MINIMUM        SUBTRACT                0
             MINIMUM        REV_SUBTRACT            0
             MINIMUM        MAXIMUM                 0
             MAXIMUM        ADD                     0
             MAXIMUM        SUBTRACT                0
             MAXIMUM        REV_SUBTRACT            0
             MAXIMUM        MINIMUM                 0

-- 3 --
       Name: opengles2
  Texlimits: 8192x8192
      Flags: (0x0000000a) hardware targettexture
Texturefmts: 8
             SDL_PIXELFORMAT_ARGB8888      0x16362004 00372645892
             SDL_PIXELFORMAT_ABGR8888      0x16762004 00376840196
             SDL_PIXELFORMAT_RGB888        0x16161804 00370546692
             SDL_PIXELFORMAT_BGR888        0x16561804 00374740996
             SDL_PIXELFORMAT_YV12          0x32315659 00842094169
             SDL_PIXELFORMAT_IYUV          0x56555949 01448433993
             SDL_PIXELFORMAT_NV12          0x3231564e 00842094158
             SDL_PIXELFORMAT_NV21          0x3132564e 00825382478
Blendmodes: NONE, BLEND, ADD, MOD, and 89996 custom blendmodes.
            Color Op       Alpha Op            Modes
             ADD            ADD                  9996
             SUBTRACT       SUBTRACT            10000
             REV_SUBTRACT   REV_SUBTRACT        10000
             MINIMUM        MINIMUM                 0
             MAXIMUM        MAXIMUM                 0
             ADD            SUBTRACT            10000
             ADD            REV_SUBTRACT        10000
             ADD            MINIMUM                 0
             ADD            MAXIMUM                 0
             SUBTRACT       ADD                 10000
             SUBTRACT       REV_SUBTRACT        10000
             SUBTRACT       MINIMUM                 0
             SUBTRACT       MAXIMUM                 0
             REV_SUBTRACT   ADD                 10000
             REV_SUBTRACT   SUBTRACT            10000
             REV_SUBTRACT   MINIMUM                 0
             REV_SUBTRACT   MAXIMUM                 0
             MINIMUM        ADD                     0
             MINIMUM        SUBTRACT                0
             MINIMUM        REV_SUBTRACT            0
             MINIMUM        MAXIMUM                 0
             MAXIMUM        ADD                     0
             MAXIMUM        SUBTRACT                0
             MAXIMUM        REV_SUBTRACT            0
             MAXIMUM        MINIMUM                 0

-- 4 --
       Name: software
  Texlimits: 0x0
      Flags: (0x00000009) software targettexture
Texturefmts: 8
             SDL_PIXELFORMAT_ARGB8888      0x16362004 00372645892
             SDL_PIXELFORMAT_ABGR8888      0x16762004 00376840196
             SDL_PIXELFORMAT_RGBA8888      0x16462004 00373694468
             SDL_PIXELFORMAT_BGRA8888      0x16862004 00377888772
             SDL_PIXELFORMAT_RGB888        0x16161804 00370546692
             SDL_PIXELFORMAT_BGR888        0x16561804 00374740996
             SDL_PIXELFORMAT_RGB565        0x15151002 00353701890
             SDL_PIXELFORMAT_RGB555        0x15130f02 00353570562
Blendmodes: NONE, BLEND, ADD, MOD, and 0 custom blendmodes.