1
\$\begingroup\$

In SDL2 there's a function to set a rectangular clip mask:

int SDL_RenderSetClipRect(SDL_Renderer* Renderer, SDL_Rect* clip);

If i call this function, copied textures will be displayed in this clip rect but not outside of it. What I'm wondering is if it's possible to set a circle as a clip?

For example, in Material Design:

There are some buttons with the shape of a circle and when you click on them, it appears a small circle from the cursor and this becomes bigger. This small circle is not display outside the button but only inside. And so, i want to do this. I want to renderer a texture that is clipped with a circle.

I don't think SDL_RenderSetClipCircle exists, so how could I emulate this?

\$\endgroup\$
1
\$\begingroup\$

Yeah, just as you thought there is no function to use a clip rectangle. However, if your use case is limited enough, you should be able to simulate this with render targets & blend-modes. Here's how you could do that:

  1. Create a render texture that is transparent and can fit your circle in it.
  2. Render your circle to the render texture.
  3. Change the blend mode to SDL_BLENDMODE_ADD.*
  4. Render whatever you want to render on top of the circle in the render texture.
  5. When done, just render the render texture to the default target (window).

*If you don't want additive blending, you could take a look at SDL_ComposeCustomBlendMode. I haven't used that myself but it looks like you might be able to implement a blend mode that takes the source color but keeps the destination alpha.

Incase you're unable to figure out the custom blend mode on your own, here's something to get you started:

 SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD);

Do note that I haven't tried this out myself, but here's how I built that blend mode: First, we wanted to keep the source color, and not let the destination color affect that. So, we simply keep the source color as what it is (so multiply by SDL_BLENDFACTOR_ONE) and zero out the destination color (SDL_BLENDFACTOR_ZERO). Those can then simply be added together to get the source color as a result. Similarly, for alpha, we wanted to keep the destination alpha, so we zero out the source alpha but keep destination alpha as what it is. These can be added together.

\$\endgroup\$
  • \$\begingroup\$ So the things above the circle will be displayed only inside the circle? \$\endgroup\$ – DiCri Apr 7 '18 at 19:34
  • \$\begingroup\$ Maybe i got what you mean, but if i have for example a circle with center point => (100, 100) and radius 50 and another circle displayed inside this circle but with center point => (100, 100) and radius 100, the result should be the first circle but of the color of the second circle. I'm explaining so bad lol \$\endgroup\$ – DiCri Apr 7 '18 at 19:44
  • \$\begingroup\$ That would be a job for a custom blend mode then, just like I described: keep destination alpha, take source color. Did you try out what I suggested? \$\endgroup\$ – Tyyppi_77 Apr 7 '18 at 21:37
  • \$\begingroup\$ so i should use custom blend mode for drawing the second circle and it will be displayed where alpha is not 0. uhm. I check out SDL_ComposeCustomBlendMode but i don't get it \$\endgroup\$ – DiCri Apr 7 '18 at 22:59
  • \$\begingroup\$ What did you not get? What did you try? It doesn't look like you've even tried out what I suggested. \$\endgroup\$ – Tyyppi_77 Apr 8 '18 at 7:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.