Alright, so I should probably get this out of the way first: I didn't do this with any sort of intention of "fighting" with your implementation--when I said "battle it out" I didn't think you'd take it so literally. I meant let the people decide which API they like better, and that's really the whole thing. This is just about APIs, and in fact I couldn't care less whose makes it in. If someone else pops up tomorrow with a third design that everyone accepts immediately I'd be just as happy.
This, then, is why I didn't instead submit it as a comment on your pull request--the fundamental design was so different that it'd basically just be saying "change the very foundations of your API" which wouldn't have accomplished anything. I figured that by designing my own API separate from yours we could have the community decide which they liked better, and
then focus on the implementation details. Implementing clipping masks isn't hard, as evidenced by the fact that someone like me with very little OpenGL knowledge could put something together. So the fact that it's taken so long for anything to come up suggests that the difficulty of the creation of this feature comes more from how to build an easy-to-understand API rather than the nitty-gritty OpenGL calls.
That is why I did this and why I said "competition's always good". I made this because I thought up an API for clipping masks that I liked while experimenting with the OpenGL stencil buffer, and thought maybe the SFML community might have some opinion on it. And that's it.
What about when people just need simple clipping for GUIs? You offer no way to utilize glScissors for simple rectangle clipping.
As I mentioned before that's one thing that your implementation provides that mine doesn't, pretty much exclusively because I was just focusing on how to get stencil tests under control.
What if someone wants to clear the mask and apply a different one? There doesn't appear to be any way to do that with your design.
There is, under the currently-named
RenderTarget::clearStencilBuffer function. There's also an alternative I mention below.
In the case of blend modes there isn't any better option but to expose the entire enums simply because there is no better way to wrap it. But when it comes to stencils I don't think we need to expose the entire interface. I mean, what exactly is the point of even giving away that the clipping API uses the stencil buffer? Isn't this kind like of exposing that the graphics module uses libjpeg?
This is not wrong, and was something I struggled with. If I'm being honest I'm not sure I'm 100% happy with the idea that
StencilSettings serves the double duty of both creating and applying masks, but I felt that with the enums 90% of users wouldn't need to care from an API standpoint, and the other 10% would be able to take advantage of it in order to do advanced stencil operations if they desired. Again, like with
BlendMode.
If we wanted to give access to the stencil buffer then we should, or we should implement clipping masks (as my design does). Just to say, what if we want to port SFML to another backend or platform that doesn't support the stencil buffer or there is a better way to implement clipping? But you can't now because you shackled one foot and one leg to the stencil buffer.
Again, more than valid. I chose the route of giving the user more flexibility if they really needed it and then hiding that power from users that don't, but of course this means the ability to use clipping masks is more tied to OpenGL stencil buffers specifically than might be otherwise.
Doesn't this totally defeat the purpose of what one of the biggest reasons is for implementing clipping masks? What if you want to limit your GUI to an area of the window but that GUI will not explicitly use the clipping mask?
If you wanted to limit a GUI to an area of the window then you'd draw a mask onto the window, then draw the GUI with
StencilTrace, ensuring that the
RenderStates are properly propagated to the GUI's children elements.
So just say a sub-drawable decides it wants its own mask - so it clears the stencil buffer (actually it needs the glClear function because this design doesn't expose that). Then it draws what it wants and returns from its draw function. Now the caller may not even know that the mask was changed (or that it may need to entirely redraw the mask, but what if it changed the mask itself?).
If a sub-drawable wants its own clipping mask, it can increment the
stencilReference member variable of the
StencilSettings object it got in its
draw call. This causes it to write different values to the stencil buffer than its parent, which can then be traced over without affecting the parent's "portion" of the screen. This is somewhat complicated, however--I will fully admit that.
https://github.com/SFML/SFML/compare/master...Kipernal:master#diff-ee21bf2821ee1b97f677cabb9bb964c5R33
This isn't how you are supposed to add gl functions.
Of course not. But as I mentioned in the comment above that line, it's not in GLLoader.hpp and I didn't want to mess with that file. I figured I'd let whoever was in charge of knowing exactly how to handle it take care of that one single function.