So a sprite would have to declare a getter/setter for every possible state: shader, view, transform, texture, blend mode.
Doesn't it already have that? I thought the point here was to keep the current Sprite API as close to what it is now as possible while allowing the new lower-level functionality.
I don't think that getting rid of global states is a good idea. It's more flexible:
It's certainly flexible, but it's not very OO. A good OO design can be just as flexible with less "gotcha!" Perhaps don't remove it entirely, but I think you should definitely try to minimize it.
The whole idea of "global" is very "blech" to me.
some states are better activated once, globally, than assigned to every entity (view, shader)
I agree that View shouldn't be part of the RenderState class idea. That's something that should be associated with a target.
It seems perfectly reasonable to me to have shaders associated with individual objects. But if not, then keep them like they are now. Separate things that you can optionally provide when you draw an object.
you can combine a transform with the current one (parent/child relationship)
I'm not sure I understand what you mean by this. It sounds like you're saying you want to combine sf::Sprite's transform with the global transform -- but doesn't that kind of defeat the point?
- an object can set the states that it needs, while enjoying other states that it doesn't care about
Are you talking about high level objects (Sprite,Text) or low level ones (Mesh)? I'm not sure I follow this either =x
Maybe my idea wasn't really clear. Let me try to better explain.
Sprite/Text API would stay pretty much the same as they are now. You'd set them up and draw them to a RenderTarget. They would be subject to further transformation by the target's View, but that's it.
The lower level API would require the user to keep a RenderState object and supply it whenever a mesh is drawn. The mesh would be subject to transformations by the RenderState and by the target's View. However since this RenderState does not have anything to do with any Sprites/Text, it wouldn't impact how those are drawn.
So to recap:
Overall association:
------------
View -> associated with RenderTarget
Color, Texture, Transform, Blend Mode -> associated with RenderState
Shader -> independent, applied per Draw() call as it is now
High level objects (Sprite/Text):
------------
Have an internal Mesh, RenderState. Drawing a sprite would probably just be a wrap around drawing its interal mesh with its internal RenderState
Low level objects (Mesh):
------------
Need to have a RenderState supplied when drawing. A shader could also optionally be supplied.
How it works:
--------------
You don't need to change any GL states between Draw calls unless the given RenderState has changed. This means any number of Meshes can be drawn, all sharing the same RenderState, and the only thing that needs to be changed is the vertex/texcoord/etc lists you pass to OpenGL.
The higher level API still works as it did before. The tradeoff of course being that you are constantly changing the render state for the sake of a simplified API.
What's more, since the RenderState embodies all the transformations, the high level API and the low level API operate independently, so you don't have to worry about the low level API "butting heads" with the high level API and causing unexpected transformations or other surprising/unpredicted render states.