SFML community forums

General => General discussions => Topic started by: Laurent on September 11, 2011, 10:40:16 pm

Title: The new graphics API in SFML 2
Post by: Laurent on September 11, 2011, 10:40:16 pm
Hi

I'm currently out of inspiration for the new graphics API. So I thought it would be a good idea to share what I've done so far, and use your feedback to complete this task :)

I decided to start with the lowest level. I needed something flexible enough so that people stop complaining about performances or limitations, but still easy to use; and as a bonus, something that will allow me to drop deprecated functions so that SFML can be ported to pure OpenGL (ES) 2 architectures.

The result is something very close to how OpenGL works, and it contains the 5 ingredients required by modern rendering architectures:

Textures
sf::Texture is left unchanged.

Shaders
sf::Shader is left unchanged, but it will later be upgraded to support vertex shaders.

Transforms
They will be handled by a new class, sf::Transform. Internally a transform is a 3x3 matrix, but its public API provides the usual functions: Translate, Rotate, Scale, Combine (with other matrix), TransformPoint, GetInverse, and some operator overloads.
So, transformations are now completely separated from drawables, and are much more flexible.

Geometry
Geometry is no longer hidden behind high-level classes, it is now directly exposed.
Vertices are defined with a new class, sf::Point. It's very simple, it contains 3 public members (Position, Color, TexCoords) as well as a bunch of constructors to easily construct points with 1, 2 or 3 of these attributes.
On top of that there's a sf::Mesh class (its name can change if you have better ideas), which is a thin layer on top of OpenGL vertex arrays. It is also quite simple: it combines a dynamic array of sf::Point (Resize, operator[], Append, ...) with a primitive type which defines how the points must be interpreted as geometrical primitives when they are rendered (for example it can be Points, Lines, Triangles, Quads, ...).

Renderer
All these things are put together in the sf::RenderTarget class (the same as now, the base of RenderWindow and RenderTexture), with the following functions:
- SetView(sf::View)
- SetTransform(sf::Transform)
- SetTexture(const sf::Texture*)
- SetShader(const sf::Shader*)
- SetBlendMode(sf::BlendMode)
- Draw(sf::Mesh)

Here is a typical example, a tiled map:
Code: [Select]
const int size = 32;

// load the texture containing all the tiles
sf::Texture tileset;
tileset.LoadFromFile("tileset.png");

// create the map
sf::Mesh map(sf::Quads, width * height * 4);
for (int x = 0; x < width; ++x)
    for (int y = 0; y < height; ++y)
    {
        int current = (x + y * width) * 4;

        // define the position of the 4 points of the current tile
        map[current + 0].Position = sf::Vector2f((x + 0) * size, (y + 0) * size);
        map[current + 1].Position = sf::Vector2f((x + 0) * size, (y + 1) * size);
        map[current + 2].Position = sf::Vector2f((x + 1) * size, (y + 1) * size);
        map[current + 3].Position = sf::Vector2f((x + 1) * size, (y + 0) * size);

        // define the texture coordinates of the 4 points of the current tile
        int tx = /* X index of the tile in the tileset */;
        int ty = /* Y index of the tile in the tileset */;
        map[current + 0].TexCoords = sf::Vector2i((tx + 0) * size, (ty + 0) * size);
        map[current + 1].TexCoords = sf::Vector2i((tx + 0) * size, (ty + 1) * size);
        map[current + 2].TexCoords = sf::Vector2i((tx + 1) * size, (ty + 1) * size);
        map[current + 3].TexCoords = sf::Vector2i((tx + 1) * size, (ty + 0) * size);
    }

// let's scale and translate the whole map
sf::Transform mapTransform;
mapTransform.Scale(2, 2);
mapTransform.Translate(500, 400);

...

// draw the map
window.SetTexture(&tileset);
window.SetTransform(mapTransform);
window.Draw(map);


Building the map is a little more verbose than with sprites, but the whole map is now a single 2D entity and it can be drawn with a single call (which is very fast -- no need for tricks such as manual clipping or pre-rendering to a texture).

That's it for the new low-level API. Hopefully, users who required more flexibility and/or performances will be happy with it.
But it's not enough: it's very low-level, a lot of SFML users enjoy the simplicity of the high-level classes and I don't want to force them to use these classes.

I can easily implement the old sf::Text, sf::Sprite and sf::Shape classes on top of this new API. But it would probably not be a good idea. These classes were required in the old API because they were the only way to draw things on screen. But now that we have a low-level layer that can do almost everything, these classes would exist only for convenience. Therefore, maybe we can think of something different. And we must also decide how these classes would mix with the low-level layer: do they define and use their own transform, or the one that is set with SetTransform? Should they inherit a base class, that would allow to write "window.Draw(sprite)"? Or rather define a Draw function in all of them so that we would write "sprite.Draw(window)"?

I actually have a lot more pending questions and problems, but let's see what you think about this ;)

Don't hesitate to comment the low-level API, suggest features or modifications, propose ideas for the high-level classes, etc. But please don't focus on details (except class names), here we are talking about general concepts.

PS: sorry for those who, after reading the title, thought that the new API was already written and pushed :lol:
Title: The new graphics API in SFML 2
Post by: Richy19 on September 11, 2011, 11:05:17 pm
I think you should create the text, sprite and shape ontop of the current API as you say people use these for convenience.
But if they want more performance they can use their custom classes with the sf::mesh
As far as how to draw them, I think you should keep it with App.Draw(sprite) try and keep it as similar to the current SFML as possible to not break everything

Does this mean that once this is done SFML 2 will be officially released?
Title: The new graphics API in SFML 2
Post by: Groogy on September 12, 2011, 12:04:11 am
First I have to say... DAMN! I'm gonna have a busy week with rbSFML *cries a little then man up*

Anyway I noticed you seemed to be using the texture width/height to define the texture coordinates, at least that's the only impression I can get since you used an integer. I really hope you won't have that in the final and that was just for example. Having texture coordinates going in the range 0..1 is standard pretty much everywhere as far as I know and it actually makes it easier. Not gonna preach on it since you said not to focus on the details but that really got me scared.

Anyway I agree that something new is entirely right since we got new tools to work with.

For instance I have had several times when the sprite has in fact been a bit annoying because all I wanted to do was render an image to a specific point on the screen and nothing more fancy. No offsetting the origin, rotating, scaling like that but just a normal "blit" like in SDL. Would be cool if SFML would now support this, might even have a mesh cached away in the render target. To show what I mean:
Code: [Select]
sf::Texture background;
background.LoadFromFile( "someFile.png" );

// ...Code here and code there...

window.Draw( background, 0, 0 );

Having a sprite for the background in a let's say static view game or menu seems unnecessary. It's a tiny short cut and you know just a comfort factor.

Other than that I have a hard time figuring out anything besides what I am already used to. Sprites, Text and Shape. Though I think there are some extensions to be made on these already in place classes. For instance what about letting us clip sprites, text and shapes by a rectangle or even another shape? Or what about skew them? Giving your users the ability to fake depth by skewing the images giving some kind of perspective.(I realize this is not done with skewing but I don't know what the other transformation is called in English)

Though I am wondering if these new things should be directly in the RenderTarget and not in the Renderer? The RenderTarget's mission is not to actually render stuff but only be a place in memory that we render to, right?

Also this is a more advanced thing I would like to see is maybe some more work on shaders? I'm stealing a little from D3D10 but let's say we want several different things to manipulate the shader a little here and a little there. What if you would allow one to have "reference" objects to variables in the shader? So instead of having to pass the shader around we have references to different variables that we can change freely. (That was the D3D10 inspiration, now comes my own idea) Though this alone I guess is not a good idea but if we combine it to like batches. So say we have obj1 and obj2 which both are going to be rendered with shader1. So instead of manipulating each variable by it's own we have an object that represents a "shader state" or something which has this objects variables defined for it and updates the shader when drawn. Am I making myself clear on it? Anyway base idea is kind of how GetMatrix worked for drawable, if any values changed recalculate the matrix. The same goes for the state kind of.

Trying on some example code:
Code: [Select]
class GameObject
{
public:
        void Render( sf::RenderTarget &aTarget ) const
        {
                // What I am talking about
                aTarget.Draw( mySprite, GetShaderState() );

               // How it is currently with the information given
               sf::Shader *shader = aTarget.GetShader();
               shader->SetParameter( blabla );
               shader->SetParameter( blabla );
               shader->SetParameter( blabla );
               shader->SetParameter( blabla );
               // ...etc
        }
private:
        mutable sf::ShaderState myState;
        sf::Sprite mySprite;
};


Get my point? I think this is actually a good idea to expand on. My initial idea might not be that great but we can work on it if we think about adding light sources, shadows and the like and passing this information on to the shader. Like let's say if we somehow add the possibility to pop and push the states?

I will expand on this shader idea tomorrow when I wake up. I believe it really have potential. For instance these can be used to optimize the bandwidth between CPU and GPU.

I believe there will be many wall of texts on this thread :P
Title: The new graphics API in SFML 2
Post by: Disch on September 12, 2011, 12:20:47 am
I'm just thinking out loud here.  Take all of this with a grain of salt:


The SetTransform and SetView thing seems a little awkward to me.  Views and Transforms seem to be very similar things.  Functionally, there isn't much that separates them, other than that a View does everything in the opposing direction.

sf::View could just be a specialized sf::Transform (inherited) which simply inverts all operations.

Then, you can remove SetView completely, and instead of an interface where you have only one view and only one transform active at any time, you allow a way to "stack" any number of transformations.

Older OpenGL did this with glPushMatrix and glPopMatrix.  I'm envisioning something similar.

The only way I can think of to do this though would make the interface awkward, though.  I don't think the user should be responsible for pushing/popping transformations and keeping track of how many are pushed.

It also makes moving the view more difficult because you have to pop all transformations, change the view, then push them all back.  You can't just set a new view as you could before.



---

Maybe that could all be avoided if you keep SetView and SetTransform, but allow ways for transformations to be stacked internally.  This would offer more or less the same functionality, but would keep the interface simpler.

You said sf::Transform was basically just a wrapper around a 3x3 matrix, right?  So then it could be as simple as overloading the * operator:

Code: [Select]

sf::Transform bos = target.GetTransform();
sf::Transform tos = bos * some_other_transformation;
target.SetTransform(tos);
target.Draw(whatever); // both 'bos' and 'some_other_transformation' applied
target.SetTransform(bos);  // effectively "popping" the stack

// from here, only 'bos' applied




again just thinking out loud....
Title: The new graphics API in SFML 2
Post by: Groogy on September 12, 2011, 12:27:39 am
I think he already thought of that because he said under Transformation that he was overloading operators :P
Title: The new graphics API in SFML 2
Post by: Walker on September 12, 2011, 04:02:27 am
I think having some more transformations (like Groogy was saying) would definitely be good. sf::Transform could even be opened up to a policy system to allow users to define their own transformations. Although this may not really fit with the S in SFML.

Other than sf::VertArray I don't think you can get much more descriptive than sf::Mesh :) Although "mesh" tends to suggest (to me) three dimensions.

It would be nice to be able to define custom blend modes with sf::BlendMode.

Overall, this looks pretty good.



Higher-level convenience classes:

You could make sf::Sprite really basic and handle texture resources internally. i.e. you could make a sprite with sf::Sprite sprite("somefile.png");

In my opinion sf::Sprite needs to have its own transform stuff - it's very easy to consider that my sprite is rotated so much. But there is always people wanting to be able to rotate about a point that is different from the sprite's "origin" so they will either need to use the lower-level system, be able to use sf::Transform with their sprites, or all of the transforms will be needed to be implemented in sf::Sprite.

I think getting rid of sf::Drawable and having the "drawable" classes as their own things sounds good.

Simple text rendering is a crucial feature but I can't think of any major improvements over the current API.
Title: The new graphics API in SFML 2
Post by: thePyro_13 on September 12, 2011, 04:08:46 am
I do hope you implement sprites and so on on top of this(or a similar simple renderable system). They provide a much higher level of simplicity than most drawing operations, and were what originally drew me to SFML.

The new API leaves room for people to squeeze performance out when they need it, just make sure you don't completely abandon the simple, or we'll just be left with FML.

Just a thought, with this new API, would it be possible to create merge-able sprites? Would make the example code even simpler, just load a tilemap like normal, than merge the lot of them. Performance and simplicity. :D
Title: The new graphics API in SFML 2
Post by: pdinklag on September 12, 2011, 07:36:56 am
I'd have to agree to what some people said here.

While, of course, classes like Sprite and Text are nothing but convenience classes which aren't technically needed, they do make the "S" in "SFML". I support the idea that it should stay simple, and these convenience classes should be implemented, but those who seek performance or more detailed control should be able to use the new API. It's a win-win that way.

What I'm not sure about is the transformation thing. Firstly, I kindof have to agree to Disch, they and views have a lot in common. Furthermore, I think that maybe the Drawable class should stay mostly as it was, basically for the same reasons I mentioned above, but also because in my eyes, this new approach is a step away from object-orientation. This may be debatable, but I think that a drawable entity is the combination of a Mesh and a Transformation, and the former API nailed it.

Besides, I would maybe rename the sf::Point class to sf::Vertex. "Point" to me sounds more like a Vector2i alias than a structure for world coords, color and tex coords.

Other than that, I like that you are now able to define custom meshes! sf::Mesh fits perfectly as the name. It was the missing link in the drawable API and completes it IMO. :)
Title: The new graphics API in SFML 2
Post by: Laurent on September 12, 2011, 08:35:15 am
Quote
Anyway I noticed you seemed to be using the texture width/height to define the texture coordinates, at least that's the only impression I can get since you used an integer. I really hope you won't have that in the final and that was just for example. Having texture coordinates going in the range 0..1 is standard pretty much everywhere as far as I know and it actually makes it easier. Not gonna preach on it since you said not to focus on the details but that really got me scared.

I'll keep pixel coordinates. I don't see how it would be better to write this:
Code: [Select]
Vector2f(static_cast<float>(x) / texture.GetWidth(), static_cast<float>(y) / texture.GetHeight())
rather than this
Code: [Select]
Vector2i(x, y)
You always have to divide by the texture size -- and not the public one, but the internal one which is not accessible (a texture may be padded if it has not power-of-two dimensions on old hardware). It's much easier to do the division internally and let people play with pixels.
But for those who use sf::Texture with OpenGL it's still possible to use normalized coordinates when binding the texture, don't worry.

Quote
For instance I have had several times when the sprite has in fact been a bit annoying because all I wanted to do was render an image to a specific point on the screen and nothing more fancy. No offsetting the origin, rotating, scaling like that but just a normal "blit" like in SDL. Would be cool if SFML would now support this, might even have a mesh cached away in the render target

Hmm, I'll have to think about this. I'm not sure it would be a good idea. I already hate having two APIs for doing the same job, so adding even more rendering options could just be confusing.

Quote
For instance what about letting us clip sprites, text and shapes by a rectangle or even another shape?

That's the RenderMask task planned for SFML 2.1. Let's not talk about this here ;)

Quote
Or what about skew them?

Can be done easily in sf::Transform. Maybe I'll even add a Skew function to it.

Quote
Giving your users the ability to fake depth by skewing the images giving some kind of perspective.(I realize this is not done with skewing but I don't know what the other transformation is called in English)

It's far more complicated to fake depth. It requires rendering tricks to get the texture correctly mapped on the triangles, "skewing" (or whatever) is not enough. There was a topic about this on the forum, search "perspective" if you want ot find it.

Quote
Though I am wondering if these new things should be directly in the RenderTarget and not in the Renderer? The RenderTarget's mission is not to actually render stuff but only be a place in memory that we render to, right?

There's no renderer anymore, RenderTarget is the only place where we can render stuff.

Quote
I will expand on this shader idea tomorrow when I wake up

Hmm, this is already a little out of topic, maybe it should have its own thread on the forum?
For SFML 2 I'll implement vertex shaders, but nothing fancy on top of it.

Quote
The SetTransform and SetView thing seems a little awkward to me. Views and Transforms seem to be very similar things. Functionally, there isn't much that separates them, other than that a View does everything in the opposing direction.

I agree. However a transform is not very convenient to handle when what you want to manipulate is a view. Because it's the same thing internally shouldn't mean that it has to be the same thing from user point of view.

Quote
Then, you can remove SetView completely, and instead of an interface where you have only one view and only one transform active at any time, you allow a way to "stack" any number of transformations

Easy to do:
Code: [Select]
Transform old = window.GetTransform();
window.SetTransform(old * new);
...
window.SetTransform(old);

EDIT: oh, this is exactly what you wrote at the end of your message :)

Quote
It also makes moving the view more difficult because you have to pop all transformations, change the view, then push them all back. You can't just set a new view as you could before.

Yep. Separating object transforms (modelview matrix) and views (projection matrix) is mandatory, they are two different things.

Quote
Simple text rendering is a crucial feature but I can't think of any major improvements over the current API.

That's right, text is a very special thing, sf::Font is hard to work with directly so I think that sf::Text will be kept unchanged in the new API.

Quote
I do hope you implement sprites and so on on top of this(or a similar simple renderable system).

That's the point of this discussion ;)

Quote
Just a thought, with this new API, would it be possible to create merge-able sprites? Would make the example code even simpler, just load a tilemap like normal, than merge the lot of them. Performance and simplicity.

This is something I'm investigating. Using high-level classes to define entities but then merging them to a single sf::Mesh (or whatever) looks like a good idea.

Quote
While, of course, classes like Sprite and Text are nothing but convenience classes which aren't technically needed, they do make the "S" in "SFML". I support the idea that it should stay simple, and these convenience classes should be implemented, but those who seek performance or more detailed control should be able to use the new API. It's a win-win that way.

I never meant to remove them. But I think we can do much better than just keep them like they are.

Quote
Furthermore, I think that maybe the Drawable class should stay mostly as it was, basically for the same reasons I mentioned above, but also because in my eyes, this new approach is a step away from object-orientation. This may be debatable, but I think that a drawable entity is the combination of a Mesh and a Transformation, and the former API nailed it.

I'm hesitating on this point. How would this mix with the low-level API? Imagine that you setup the position/rotation of a sprite, then call SetTransform(whatever) and draw your sprite. What transform is applied to the sprite? Only its own transform? A combination of it and the global one?

Quote
Besides, I would maybe rename the sf::Point class to sf::Vertex. "Point" to me sounds more like a Vector2i alias than a structure for world coords, color and tex coords.

I was not sure if "vertex" was meaningful enough for people not familiar with 3D rendering.
Obviously, I need feedback from people who speak english better than me here :)
Title: The new graphics API in SFML 2
Post by: Contadotempo on September 12, 2011, 02:47:47 pm
This question is coming from someone who knows nothing about this subject but I got curious:
If sf::Text was to be removed, what other ways would there be to display a simple text?
Title: The new graphics API in SFML 2
Post by: Laurent on September 12, 2011, 03:20:19 pm
Quote
If sf::Text was to be removed, what other ways would there be to display a simple text?

Already answered:
Quote from: "Laurent"
That's right, text is a very special thing, sf::Font is hard to work with directly so I think that sf::Text will be kept unchanged in the new API.
Title: The new graphics API in SFML 2
Post by: Hiura on September 12, 2011, 03:55:50 pm
Quote from: "Laurent"
And we must also decide how these classes would mix with the low-level layer: do they define and use their own transform, or the one that is set with SetTransform? Should they inherit a base class, that would allow to write "window.Draw(sprite)"? Or rather define a Draw function in all of them so that we would write "sprite.Draw(window)"?

To keep thing simple I would say it should be consistent between the mesh-part and the high-level-part. What I suggest is to have two different and separated hierarchies of classes and to change a little bit what you describe in your first post with Transform, Mesh and Texture like this :

First, wrap the three new Transform, Mesh and Texture classes in, I don't know, DrawableMesh class. This class can have no texture if needed.
That would be the first class hierarchy. Without any child class. (I don't see what class should inherit from DrawableMesh but maybe I missed something.)

So your example would look like :
Code: [Select]
const int size = 32;

// load the texture containing all the tiles
sf::Texture tileset;
tileset.LoadFromFile("tileset.png");

// create the map
sf::Mesh map(sf::Quads, width * height * 4);
for (int x = 0; x < width; ++x)
    for (int y = 0; y < height; ++y)
    {
         /* same */
    }

// let's scale and translate the whole map
sf::Transform mapTransform;
mapTransform.Scale(2, 2);
mapTransform.Translate(500, 400);

...

DrawableMesh dm(map, mapTransform, tileset); // (*)

// draw the map
window.Draw(dm);


(*) Here there is one downside : we have to keep four objects alive instead of three which is already huge. To simply thing, a fourth argument could be added to specify a copy/ownership policy like MovePolicy (C++11 only), CopyPolicy or ReferencePolicy. I don't know exactly how it should be done properly, though. Or maybe the mesh and the transformation could be copied and only the DrawableMesh object and the Texture object should be kept alive.

Next, the second class hierarchy would be the same as the current sf::Drawable. Only it's internal implementation would change to use the DrawableMesh class EDIT : this is wrong. SetTransform or alike should replace SetScale, ... to be consistent. (Or maybe it could be the same as it currently is.)

With this two hierarchy we would have the same line of code to render stuff :
Code: [Select]
window.Draw(drawableMesh);
window.Draw(drawable);


And the user can choose between low-level API with Meshes and so on; or use the high-level API with Sprite/Text/Shape as one can do with the current API.

From the RenderTarget's point of view it would mean two Draw functions :
Code: [Select]
void Draw(const Drawable& object);
void Draw(const DrawableMesh& object);


What do you thing of this ? Have I missed something and my whole idea fells apart ?
Title: The new graphics API in SFML 2
Post by: luiscubal on September 12, 2011, 03:59:47 pm
Quote
Or rather define a Draw function in all of them so that we would write "sprite.Draw(window)"?

I like this idea. Besides, even if SFML 2 were to remove the equivalent functionality, the effective end-result would be that people would re-implement these classes themselves.

Also, if you dislike adding junk to the core, you could add a separate library SFML-SimpleGraphics, or something like that, where these extra high-level functions would be.

Quote
sf::Point. It's very simple, it contains 3 public members (Position, Color, TexCoords) as well as a bunch of constructors to easily construct points with 1, 2 or 3 of these attributes.

What if I want to pass extra-data per-Point to the shader.
Title: The new graphics API in SFML 2
Post by: Laurent on September 12, 2011, 04:03:04 pm
Quote
What if I want to pass extra-data per-Point to the shader.

Calm down :D
Seriously, this is not likely to happen soon. You're already looking too far.
Title: The new graphics API in SFML 2
Post by: Laurent on September 12, 2011, 04:03:55 pm
Quote
What do you thing of this ? Have I missed something and my whole idea fells apart ?

I need more time to think about it, I'll answer later ;)
Title: The new graphics API in SFML 2
Post by: Laurent on September 13, 2011, 09:31:36 am
Quote
First, wrap the three new Transform, Mesh and Texture classes in, I don't know, DrawableMesh class. This class can have no texture if needed.
That would be the first class hierarchy. Without any child class. (I don't see what class should inherit from DrawableMesh but maybe I missed something.)
[...]
Here there is one downside : we have to keep four objects alive instead of three which is already huge. To simply thing, a fourth argument could be added to specify a copy/ownership policy like MovePolicy (C++11 only), CopyPolicy or ReferencePolicy. I don't know exactly how it should be done properly, though. Or maybe the mesh and the transformation could be copied and only the DrawableMesh object and the Texture object should be kept alive.

BlendMode, Transform and View should always be handled by value (copy), whereas Texture and Shader should be handled by reference. To make it clear, the first three will be passed as const references and the last two will always be passed as const pointer to functions that use them.

Therefore, following your idea, the DrawableMesh class would store a pointer to a texture and a copy of a transform and a mesh. But how would they be accessed after the object is constructed? Wouldn't it be too verbose, compared to just storing the 3 objects (texture/mesh/transform) separately? You would have to get/set them everytime you want to change them
Code: [Select]
sf::Transform transform = drawable.GetTransform();
transform.Rotate(45);
drawable.SetTransform(45);

In other words, what does this additional class bring?
Title: The new graphics API in SFML 2
Post by: gsaurus on September 13, 2011, 12:24:16 pm
I think that Hiura idea is to avoid having SetTexture and SetTransform on Window so that it doesn't interfere with Sprites transformations. The DrawableMesh seems only a way to aggregate mesh, texture and transform, so that everything use Window.Draw. We can achieve the same effect with a Draw taking 3 arguments, instead of an extra class:
Code: [Select]
// draw the map
window.Draw(map, &tileset, mapTransform);
// draw a sprite
window.Draw(mySprite);

But I don't like the idea, what if we want to use the same texture or the same transformation for several maps? We'd have to repeatedly apply the texture and transformation. This isn't the best solution.
Title: The new graphics API in SFML 2
Post by: Laurent on September 13, 2011, 12:27:46 pm
Quote
But I don't like the idea, what if we have several maps using the same texture? What if we want to do some draws with the same transform applied? We'd have to repeatedly apply the texture and transformation. This isn't the best solution.

I totally agree. Although I don't like global render-states, I admit that they are much more flexible when low-level functions are involved.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 13, 2011, 12:44:44 pm
I don't see the problem on a Sprite class having it's own transform.
Code: [Select]
window.SetTexture(someTexture);    // set a texture for maps
window.SetTransform(someTrasnform) // some global transformation from now on

// draw a sprite:
// sprite transform is combined with the global one.
// the previous transform and texture are restored after this draw
window.Draw(mySprite);

I think it's not confusing, if we specifically apply a transform on a window we know that everything that we'll draw next will be deformed that way. If we have a sprite in position (300,120) we know that it will suffer the global transformation as well.

This will only happen if someone want to use low level things (that person should know what is doing then). Mixing low level with high level sprites can be convenient sometimes. But one using only high level features doesn't have to use SetTexture/SetTransform and everything works as it was before.
Title: The new graphics API in SFML 2
Post by: Laurent on September 13, 2011, 12:58:30 pm
Quote
I think it's not confusing, if we specifically apply a transform on a window we know that everything that we'll draw next will be deformed that way. If we have a sprite in position (300,120) we know that it will suffer the global transformation as well

I think this is very confusing: the other states (blend mode, texture) are overwritten, but the transform is combined with the global one.

I don't like having two APIs that can achieve the same results differently, so at least let's keep their interactions as clean and intuitive as possible. That's just my point of view ;)
Title: The new graphics API in SFML 2
Post by: Hiura on September 13, 2011, 09:16:04 pm
I'll just write as my mind goes.

Quote from: "Laurent"
In other words, what does this additional class bring?
Mainly a better consistency between the two different high and low level APIs.

Quote from: "gsaurus"
I think that Hiura idea is to avoid having SetTexture and SetTransform on Window so that it doesn't interfere with Sprites transformations.
Yes, but also to have the same code structure on both sprites/texts/... and meshes.

Quote from: "gsaurus"
We can achieve the same effect with a Draw taking 3 arguments, instead of an extra class
From SFML point of view it would be the same. But from the user point of view it would be a little bit different : for example if you're storing your graphical object in a vector then you need to store a tuple of three object instead of only one.

As I write these lines I realize that most people wouldn't store graphics object directly but instead have classed like this one :
Code: [Select]
class XYZ {
  sf::Mesh myMesh;
  sf::Tranform myTrans;
:
:

So when it comes to storing data it don't change much between the wrapping DrawableMesh class and the three-arguments Draw method.

Quote from: "gsaurus"
But I don't like the idea, what if we want to use the same texture or the same transformation for several maps? We'd have to repeatedly apply the texture and transformation.
Are you thinking that performance will be an issue with this system ? I don't think so because it's very rare to keep the same texture / transformation to draw several objects. If I'm not wrong on that last fact the performance shouldn't be a issue in most cases.

Even if you have a lot of objects with the same texture then you need a very specific data structure to take part of this new system. And even with this data structure I think most user will call SetTexture even if it's not necessary just in case they have a flaw in on of their application module. (Ok, this is not a good argument because this would be a mistake to proceed like this and not fix the bug.)

My point is their wouldn't be so much different (performance-speaking or program-design-speaking) between calling window.SetTexture when drawing and drawableMesh.SetTexture when setting up the dm object.

Quote from: "Laurent"
Therefore, following your idea, the DrawableMesh class would store a pointer to a texture and a copy of a transform and a mesh. But how would they be accessed after the object is constructed? Wouldn't it be too verbose, compared to just storing the 3 objects (texture/mesh/transform) separately? You would have to get/set them everytime you want to change them
Yes, unfortunately. Because duplicating the API and add Scale, Rotate, ... to DrawableMesh would be a bad idea.

Quote
This isn't the best solution.
Definitely not, I agree.

So the Draw(mesh, texture, tranform) looks better than my idea. It also look consistent with Draw(sprite) if Sprite have their own Texture and Tranform. (Mixing window.Set[Texture|Transform]+window.Draw(mesh) and window.Draw(sprite) is confusing for me too.)

Maybe to add more flexibility to Draw(mesh, texture, tranform) version (let's call it gsaurus' idea for convenience if you don't mind) RenderTarget can have these overloads :
Code: [Select]
Draw(Mesh, Transform, Texture) // update current Texture and Transform
Draw(Mesh, Transform) // keep current Texture
Draw(Mesh, Texture) // keep Texture
Draw(Mesh) // keep both
Draw(Sprite/Text/...) // Use sprite's Transform and Texture


But the last one has still something confusing : does it update or keep the current Texture and Transform ? It would be easy if Sprite-like doesn't own their Transform and Texture. So is it possible ? It's possible only if all sprite-like have both Texture and Transform without specific requirement.

Can a Text have a specific texture ? (Would it be feasible for the implementation to display an image "in" the text's characters ?) Yes, I think so.

Because every sprite-like can have both Transform and Texture and doesn't have any specific requirement on these (or did I miss something there ?) I think sprite-like shouldn't have their own Transform and Texture.

To sum up my thoughts :
I agree that the DrawableMesh is not a good idea and that having these overload in RenderTarget should keep things consistent between the two high and low APIs :
Code: [Select]
Draw(Mesh, Transform, Texture) // update current Texture and Transform
Draw(Mesh, Transform) // keep current Texture
Draw(Mesh, Texture) // keep current Transform
Draw(Mesh) // keep both
Draw(Sprite/Text/..., Transform, Texture) // update current Texture and Transform  
Draw(Sprite/Text/..., Transform) // keep current Texture
Draw(Sprite/Text/..., Texture) // keep current Transform
Draw(Sprite/Text/...) // keep both

And if one doesn't want any texture he/she can call Draw(mesh or sprite-like, 0) or Draw(mesh or sprite-like, transform, 0) depending on the need to change the transformation.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 13, 2011, 09:52:29 pm
Quote from: "Hiura"
for example if you're storing your graphical object in a vector then you need to store a tuple of three object instead of only one.

Consider using a vector of Sprites instead (if a sprite already have those three elements). At low level it's up to the user to decide how to organize the resources.

Quote from: "Hiura"
it's very rare to keep the same texture / transformation to draw several objects. If I'm not wrong on that last fact the performance shouldn't be a issue in most cases.

Example: RPG game using a unique tileset for everything: background, characters (including animations), etc.

Quote from: "Hiura"
Code: [Select]
Draw(Mesh, Transform, Texture) // update current Texture and Transform
Draw(Mesh, Transform) // keep current Texture
Draw(Mesh, Texture) // keep Texture
Draw(Mesh) // keep both
Draw(Sprite/Text/...) // Use sprite's Transform and Texture

But the last one has still something confusing : does it update or keep the current Texture and Transform?

So this is exactly the same problem as if we're using SetTransform/SetTexture:
Code: [Select]
window.SetTexture(someTexture);
window.SetTransform(someTrasnform);
window.Draw(mySprite); // will it use it's own Transform or a combination with the global one?


I can't think of anything right now, I need some food  :P
Title: The new graphics API in SFML 2
Post by: Laurent on September 13, 2011, 10:05:50 pm
Quote
Code: [Select]
Draw(Mesh, Transform, Texture) // update current Texture and Transform
Draw(Mesh, Transform) // keep current Texture
Draw(Mesh, Texture) // keep current Transform
Draw(Mesh) // keep both
Draw(Sprite/Text/..., Transform, Texture) // update current Texture and Transform  
Draw(Sprite/Text/..., Transform) // keep current Texture
Draw(Sprite/Text/..., Texture) // keep current Transform
Draw(Sprite/Text/...) // keep both

Definitely not doable in my opinion, it will explode if you add BlendMode, Shader and View. And future other states (RenderMask for example).
And it will complicate the life of people who write bindings where function overloading is not supported :)
Title: The new graphics API in SFML 2
Post by: Disch on September 14, 2011, 01:20:20 am
It sounds like the problem here is that there needs to be a global render state to accomidate the Mesh idea, but the Sprite idea needs its own render state that operates independently.


So how about introducing a new RenderState object?  When drawing a mesh, you would supply the desired RenderState (would have to be a mandatory parameter).  When drawing a Sprite, it would generate its own:

Code: [Select]

sf::RenderState lowlevelstate;
lowlevelstate.SetTexture( blah );
lowlevelstate.SetWhatever( whatever );

sf::Mesh mymesh = blah;
sf::Sprite mysprite = blah;

target.Draw( mymesh, lowlevelstate ); // uses low-level state
mysprite.Draw(target);  // uses sf::Sprite's internal state


sf::Sprite's Draw function would probably internally just manipulate it's own state and call target.Draw( spritemesh, spritestate ); or whatever.
Title: The new graphics API in SFML 2
Post by: Laurent on September 14, 2011, 07:54:13 am
Quote
So how about introducing a new RenderState object? When drawing a mesh, you would supply the desired RenderState (would have to be a mandatory parameter). When drawing a Sprite, it would generate its own:

So a sprite would have to declare a getter/setter for every possible state: shader, view, transform, texture, blend mode.

I don't think that getting rid of global states is a good idea. It's more flexible:
- some states are better activated once, globally, than assigned to every entity (view, shader)
- you can combine a transform with the current one (parent/child relationship)
- an object can set the states that it needs, while enjoying other states that it doesn't care about

My plan was to use solution 3: a sprite has its own texture, therefore it overwrites the global one when it's rendered but still uses any shader/view/whatever which is active at that time.
Title: The new graphics API in SFML 2
Post by: Lo-X on September 14, 2011, 08:32:20 am
I don't understand all the points but as a begginer I prefer Hiura's solution than to do :

Code: [Select]
window.SetTransform(transform);
window.SetTexture(texture);
window.Draw(Mesh);

and suddenly

window.Draw(sprite);


Furthermore I don't understand why that's the window which have membres like SetTransform and SetTexture. In fact, I understand because OpenGL in the background works like that but for me these members should belong to a "drawable", something that can be drawn directly by the window.

I understand that what I describe is the old API and that it's difficult to find something between the old one and a low level API.
Title: The new graphics API in SFML 2
Post by: Laurent on September 14, 2011, 08:56:03 am
Quote
I don't understand all the points but as a begginer I prefer Hiura's solution than to do

Which one? A DrawableMesh with texture/transform/mesh, or a Draw function which takes any combination of those?

Quote
Furthermore I don't understand why that's the window which have membres like SetTransform and SetTexture. In fact, I understand because OpenGL in the background works like that but for me these members should belong to a "drawable", something that can be drawn directly by the window.

Like I said, some states are better set globally than assigned per object, like shader and view.
And if all states were encapsulated in objects, I'm pretty sure that people would soon be tired of all those repeated Get/Set to modify them.
Title: The new graphics API in SFML 2
Post by: Hiura on September 14, 2011, 09:43:17 am
Quote from: "Laurent"
Definitely not doable in my opinion, it will explode if you add BlendMode, Shader and View. And future other states (RenderMask for example).
Yes, you're write! (Again!  :P )

Quote from: "Hiura"
But the last one has still something confusing : does it update or keep the current Texture and Transform ? It would be easy if Sprite-like doesn't own their Transform and Texture. So is it possible ? It's possible only if all sprite-like have both Texture and Transform without specific requirement.

Can a Text have a specific texture ? (Would it be feasible for the implementation to display an image "in" the text's characters ?) Yes, I think so.

Because every sprite-like can have both Transform and Texture and doesn't have any specific requirement on these (or did I miss something there ?) I think sprite-like shouldn't have their own Transform and Texture.

What about that ? If sprite-like don't have their own render state then we can do something consistent and logical :
Code: [Select]
window.SetTransform(...);
window.Set....();

window.Draw(mesh);
window.Draw(sprite); // use same transform / texture
(Only two overloads.)

Now, what would be different in sprite-like and mesh ? The only fundamental difference I see is that sprite would have only TextCoord parameter.

Quote from: "Laurent"
My plan was to use solution 3: a sprite has its own texture
What about Text ? Ho, and will Shape still exist or it will replaced completely by Mesh (with some static function to have a high level API in order to create rectangle/lines/circle) ?

If they all have their own texture then mesh could also have its own one, right ? It would make things less confusing.
Title: The new graphics API in SFML 2
Post by: Laurent on September 14, 2011, 10:02:59 am
Quote
If sprite-like don't have their own render state then we can do something consistent and logical

But higher-level objects need to have their own render states, otherwise they are pretty useless ;)
What is a sprite without a texture? Would you bind the text's texture from its font manually?

Quote
What about Text ?

I think that sf::Text won't change much.

Quote
Ho, and will Shape still exist or it will replaced completely by Mesh (with some static function to have a high level API in order to create rectangle/lines/circle) ?

That's the main point of the discussion, so I'm waiting for your suggestions :)

Quote
If they all have their own texture then mesh could also have its own one, right ? It would make things less confusing

Are you just talking about texture, or all other states too? If texture only, why would this state be a special case? And how would other states be handled?
Title: The new graphics API in SFML 2
Post by: Hiura on September 14, 2011, 10:30:36 am
Quote
What is a sprite without a texture?
A colored rectangle. Ok a shape... So they would be quite the same. Shape (with optional texture) and Sprite I mean. Would we need both ?

Quote
Would you bind the text's texture from its font manually?
In fact, I was not speaking about the font texture but what you can draw "in" the characters. Sorry for the misunderstanding here.

Quote
Are you just talking about texture, or all other states too? If texture only, why would this state be a special case? And how would other states be handled?
Only about texture, because it is something that both sprite-like and mesh have in common. Moreover, when I think about something to draw I think of its shape (Mesh/Sprite/Text) _and_ its color/texture. Then comes the part of positioning it on the world (Transform), etc...
Other states would be directly Set on the render target.

(As for the implementation if two consecutively drawn objects have the same texture then we do not have to load it again (from OpenGL pov). So it won't change anything performance-speaking.)

Gosh! It's a complicated!  :P
Title: The new graphics API in SFML 2
Post by: Laurent on September 14, 2011, 11:01:59 am
Quote
A colored rectangle. Ok a shape... So they would be quite the same. Shape (with optional texture) and Sprite I mean. Would we need both ?

Technically we can definitely merge them, but their public API is quite different. It would be a weird mix: a sprite with a colored outline? a custom shape with a subrect? ....

Quote
In fact, I was not speaking about the font texture but what you can draw "in" the characters. Sorry for the misunderstanding here.

Characters are not geometrical entities, they are quads mapped with the font's texture. So you can't draw anything inside them.

Quote
As for the implementation if two consecutively drawn objects have the same texture then we do not have to load it again (from OpenGL pov)

It's far from being as easy as it looks, trust me :lol:

Quote
Gosh! It's a complicated!

Yeah... otherwise it would already be implemented and I would be thinking about SFML 3 ;)
Title: The new graphics API in SFML 2
Post by: Hiura on September 14, 2011, 11:07:39 am
Quote
Characters are not geometrical entities, they are quads mapped with the font's texture. So you can't draw anything inside them.
Ho! So it change everything ! Texture is no more something in common for these classes so my argumentation doesn't work...
Title: The new graphics API in SFML 2
Post by: gsaurus on September 15, 2011, 01:04:08 am
So, it's ok to assume that Draw(sprite) overrides texture with it's own, the problem is the transform (override or combine with the global state is not clear).

A not so elegant solution is to keep transform out of Sprite/Shape/Text, and let user decide how to store/apply transformation. The main purpose of these classes is to hide the manipulation of a mesh & texture after all.
This solution is more verbose, not so intuitive, but it doesn't break with the global states concept (and can encourage MVC by keeping sprite independent of transform).

Often users doesn't even need rotation (n)or scale, so they can have their own class with their own x,y fields if they want, and create a Transform on the fly (though keeping a Transform object is just the same)
Also often they use constants to draw static stuff like background sprites. Sometimes they just want to draw something in some place, they don't really want to keep a transform state.

Code: [Select]
class MyCharacter{
    ...
    sf::Transform transform;
    sf::Sprite representation;
    ...
};

...

window.SetTransform( myChar.GetTransform() );
window.Draw( myChar.GetRepresentation() );

sf::Sprite background;
window.SetTransform( sf::Transform( 100, 200) );
window.Draw(background);


The drawback is that we're applying the transform to the window, instead of to the sprite, which is weird for beginners.

I'm just pointing alternatives so we can think about it, not necessarily suggesting them as if they were better.

I think we'll have to abdicate of something for a reasonable solution :?
Title: The new graphics API in SFML 2
Post by: Disch on September 15, 2011, 04:48:03 am
Quote from: "Laurent"
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.

Quote
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.

Quote
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.

Quote
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?

Quote
- 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.
Title: The new graphics API in SFML 2
Post by: Laurent on September 15, 2011, 08:14:15 am
Quote
A not so elegant solution is to keep transform out of Sprite/Shape/Text, and let user decide how to store/apply transformation. The main purpose of these classes is to hide the manipulation of a mesh & texture after all.

This is a valid solution, but the transform part of the current API (set/get position/rotation/scale/origin) is also what makes the S of SFML, I feel like dropping it would be too abrupt.

Quote
Doesn't it already have that?

No, current classes only have accessors for their relevant states, not all possible ones.

Quote
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.

No! The point is to find something new that's much better than the current API. Ok, maybe the final result will be something very close to it, but please try to be as open as possible ;)
If the goal was just to reimplement the current API... well it's already done.

Quote
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.

This is something that I don't like (global states), so if we can find an alternative solution that doesn't remove this flexibility I'm ready to get rid of them ;)

Quote
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?

I'm not talking about sprites. It's a very common use case to draw hierarchical objects, ie. combine an object's (the child) transform with the current one (set by the parent).

Quote
Are you talking about high level objects (Sprite,Text) or low level ones (Mesh)? I'm not sure I follow this either =x

I think we're talking about the low-level API, aren't we? :D

Quote
Maybe my idea wasn't really clear. Let me try to better explain.

It's very clear now, thanks ;)
I think your point of view makes sense and is consistent.

However I have some questions:
- what does the RenderState class look like?
--> how do we avoid get/set transform every time we want to modify it?
--> is the texture a read-only (const) pointer or not?
- why do you keep the shader out of RenderState?
- Sprite::SetTransform, or Sprite::SetPosition/Rotation/etc.?
- isn't it confusing to have 3 different ways to handle states? (ok, I know it's already like this currently)

Quote
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.

Like I said, implementing a cache system is not as easy as it looks. Look at all the tricky bugs in SFML 2 that involve the sf::Renderer class...

Quote
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.

It's indeed an excellent point.

And how would you draw a sprite, by the way? Sprite.Draw(window, shader) or window.Draw(sprite, shader)?
Title: The new graphics API in SFML 2
Post by: Lo-X on September 15, 2011, 02:16:33 pm
Quote from: "Laurent"
And how would you draw a sprite, by the way? Sprite.Draw(window, shader) or window.Draw(sprite, shader)?


The drawing action is not made by the sprite but by the window, no ?
I think that's not logical if the sprite is drawn by itself.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 15, 2011, 02:58:43 pm
Quote from: "Laurent"
--> how do we avoid get/set transform every time we want to modify it?

I have a slightly different suggestion.
Code: [Select]
sf::RenderState lowLevelState;
lowLevelState.SetTexture( ... );
...
target.SetRenderState(state);
target.DrawMesh(mesh); // or target.Draw(mesh), but target.DrawMesh is more explicit (*)
target.Draw(sprite); // override the render state (and restore it back after drawing)


This way we are explicitly affecting the whole state at once for the low level meshes. Though we know that Sprite has it's own RenderState so there's no doubt that it will be drawn with it independently.
(*) target.DrawMesh makes more explicit the difference between mesh and Sprite/Text (mesh doesn't have it's own RenderState while high level classes does). But just Draw is also ok, it' simpler.


Alternatively create a low level Renderer (again...) to render meshes and handle global state independently of the higher level RenderTarget. Though it's not as low and flat as it was on the previous versions.
Code: [Select]
target.Draw(sprite); // High level API
sf::Renderer renderer = target.GetRenderer(); // access to the low level API)
renderer.SetTransform(...);
rendere.DrawMesh(myMesh);
Title: The new graphics API in SFML 2
Post by: Laurent on September 15, 2011, 05:17:20 pm
Quote
The drawing action is not made by the sprite but by the window, no ?
I think that's not logical if the sprite is drawn by itself.

Yes, but... this requires a base class (sf::Drawable) with at least a virtual Draw function.
With "sprite.Draw(window)" there's no need for such a class, everybody can write a new class that can be drawn like the existing ones.

Quote
I have a slightly different suggestion.

But you still have to Get/Set the transform before/after modifying it, right? Compared to the case where you directly own the sf::Transform instance.
And how is it better than setting each state independantly? Does it mean that you have to define every state every time you want to change something?

Quote
Alternatively create a low level Renderer (again...) to render meshes and handle global state independently of the higher level RenderTarget. Though it's not as low and flat as it was on the previous versions.

Same here, I can see that it's more complicated but I can't find what advantages it brings :)
Title: The new graphics API in SFML 2
Post by: Disch on September 15, 2011, 06:44:05 pm
Quote from: "Laurent"
No! The point is to find something new that's much better than the current API. Ok, maybe the final result will be something very close to it, but please try to be as open as possible


Okay.  that was my misunderstanding.  =P

I'll think about this more when I get some free time.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 15, 2011, 08:50:25 pm
Quote from: "Laurent"
Quote
I have a slightly different suggestion.

But you still have to Get/Set the transform

If you're referring to sprite, no, it has it's own transform.

Both suggestions are attempts to sugar the two APIs to solve this ambiguity:
Code: [Select]
target.SetTransform(...)
target.Draw(sprite); //how does it interact with global transform?

The first suggestion wraps the state properties into one concept (RenderState), as proposed before, but allow it to be applied globally on the RenderTarget, or "localy" by drawing a high level object (which owns it's own RenderState). This is probably not explicit enough, but it was an attempt to make explicit that sprite draws with it's own RenderState, while meshes use the global state. Though if we just want to change one property (like Texture) it's silly to create one RenderState just for that.


On the second I was trying to separate the two APIs: keeping high level operations at RenderTarget and low level at Renderer, to make explicit that RenderTarget.Draw doesn't affect the global state.




Perhaps renaming the SetTransform/SetTexture at RenderTarget would make it explicit? (rename like what? I don't know).

A question, what happens if you have different targets? Each target has it's "global" rendering state? or there is a global state for everything? In that case it would be needed a static class to deal with the state alone (there's mouse & keyboard already, so..)
Title: The new graphics API in SFML 2
Post by: Richy19 on September 15, 2011, 09:38:32 pm
Laurent, any advances on this or an ETA?
Title: The new graphics API in SFML 2
Post by: Laurent on September 16, 2011, 08:53:44 am
Quote
If you're referring to sprite, no, it has it's own transform.

No, I mean:
Code: [Select]
sf::RenderStates states;
...
// I want to rotate
sf::Transform transform = states.GetTransform(); // I have to retrieve the transform first
transform.Rotate(45);
states.SetTransform(transform); // then assign it back


Quote
it was an attempt to make explicit that sprite draws with it's own RenderState, while meshes use the global state

So there no way to mix meshes (global) states and sprites/whatever states? Both APIs should not be 100% separated, they will often be mixed. Because some states have to be shared (view, shader).

Quote
Though if we just want to change one property (like Texture) it's silly to create one RenderState just for that.

Yep, another point against this new layer between states and the RenderTarget.

Quote
On the second I was trying to separate the two APIs: keeping high level operations at RenderTarget and low level at Renderer, to make explicit that RenderTarget.Draw doesn't affect the global state.

In fact, if all we see for high-level objects is 'object.Draw(window)', I think it's already clear enough that this won't change global states. All this function does is to draw the object.

Quote
Perhaps renaming the SetTransform/SetTexture at RenderTarget would make it explicit?

Why?

Quote
A question, what happens if you have different targets? Each target has it's "global" rendering state? or there is a global state for everything?

Each target has its own states. It would be silly to have non-static setters that would set states globally on all instances.

Quote
Laurent, any advances on this or an ETA?

Nothing more than what you can read here.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 16, 2011, 01:59:51 pm
Quote from: "Laurent"
In fact, if all we see for high-level objects is 'object.Draw(window)', I think it's already clear enough that this won't change global states.

That should do  8). But how is the mesh drawn? window.Draw(mesh), i.e., in opposite to the high level object.Draw(window)? :roll:

Quote
Each target has its own states. It would be silly to have non-static setters that would set states globally on all instances.

If it was global on all instances, all the state setters was going to be in a static class, like Keyboard/Mouse, the global states manipulation was going to be all separated from RenderTarget. That would allow one to use the same texture to draw on several images, etc. But that's not really an issue :lol:, I like the states by target strategy, it makes it more OO :wink:
Title: The new graphics API in SFML 2
Post by: Hiura on September 16, 2011, 02:52:29 pm
Quote
If it was global on all instances, all the state setters was going to be in a static class, like Keyboard/Mouse, the global states manipulation was going to be all separated from RenderTarget.
How would you be able to draw something in a render image while you're drawing stuff in the window at the same time ? It seems quite complicated because you have to first save somehow the render state you're using to draw in the window, then set the render state for the render image and finally set the first render state back to continue drawing in the window. It might even be impossible if you're using more than one thread.

If you're planing to use sprite.Draw(target) I suggest renaming Draw to something else (like DrawOn, for example).

Also, mixing target.Draw(mesh) and sprite.Draw(target) is confusing I think. Why sprites would be drawn differently ? (Or why mesh would be drawn differently ?)

If you want to keep "target.Draw(xyz)" syntax and to express the fact that sprite and mesh are not drawn in the same render state, maybe (and only maybe) having "target.DrawMesh(mesh)" and "target.Draw(sprite)" (or any pair of two different names) could be a solution. This could imply something like "target.SetMeshTransform(...)" for meshes and "target.SetTransform" for sprites, ... and so on for any render state properties (*). It's more verbose, OK, but it can (if the methods' name are well chosen) express the fact that mesh's render state are not shared with sprite's render state.

(*) except for texture : if sprite owns their texture we can have "target.SetMeshTexture" and "sprite.SetTexture".

Is renaming methods while keeping most of the design exposed in Laurent's first post a valid solution in your opinion ?
Title: The new graphics API in SFML 2
Post by: Laurent on September 16, 2011, 04:36:20 pm
Quote
But how is the mesh drawn? window.Draw(mesh), i.e., in opposite to the high level object.Draw(window)?

It's a detail, I don't think we should waste too much time on it.

Quote
If you want to keep "target.Draw(xyz)" syntax and to express the fact that sprite and mesh are not drawn in the same render state, maybe (and only maybe) having "target.DrawMesh(mesh)" and "target.Draw(sprite)" (or any pair of two different names) could be a solution

Instead of talking about functions names, we should discuss the design first ;)
Why do you think that meshes and high-level objects shouldn't share the same states? I had the feeling that it would be better if they were mixed, high-level objects would just be a layer on top of the low-level API instead of a separate layer.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 16, 2011, 05:16:31 pm
Quote from: "Laurent"
Why do you think that meshes and high-level objects shouldn't share the same states?

For simplicity of the high-level objects, to keep their own state, or part of the state (texture, transform).

If high-level objects use the global state as is, then you'll have sprites/whatever without their own texture & transform.
You can still store their own state internally but you have to explicitly apply it to the render target if you don't want to use/mix with the current global state - resulting in more verbosity.
Code: [Select]
sf::Sprite sprite(someTexture);
sprite.SetPosition(200,100);
window.SetTexture(sprite.GetTexture()); // 1
window.SetTransform(sprite.GetTransform()); // 2
window.Draw(sprite); // 3


The naming issue previously said are to turn 1,2 and 3 in one step, with the side effect of no chance to use the current global texture and transform. As for the other properties like shader, those have to be shared. Again, how it sounds can be a question of function names.[/code]
Title: The new graphics API in SFML 2
Post by: Hiura on September 16, 2011, 05:22:57 pm
Quote from: "Laurent"
Why do you think that meshes and high-level objects shouldn't share the same states? I had the feeling that it would be better if they were mixed, high-level objects would just be a layer on top of the low-level API instead of a separate layer.
Why ? Because I'm getting confused !  :oops:

Quote from: "Laurent"
I can easily implement the old sf::Text, sf::Sprite and sf::Shape classes on top of this new API. But it would probably not be a good idea.
Quote from: "Laurent"
But higher-level objects need to have their own render states, otherwise they are pretty useless

Maybe I misunderstood your words but these two quotes seems to go the opposite way from one other.

A lot have been said and everybody has changed his mind at least three times. Maybe it would be a good idea to make a quick recap of which ideas seem good so far.
Title: The new graphics API in SFML 2
Post by: Laurent on September 16, 2011, 05:36:37 pm
Quote
Code: [Select]
sf::Sprite sprite(someTexture);
sprite.SetPosition(200,100);
window.SetTexture(sprite.GetTexture()); // 1
window.SetTransform(sprite.GetTransform()); // 2
window.Draw(sprite); // 3

When the sprite is drawn it sets all its internal states first so you don't have to do 1 and 2.
That my point: high-level objects can set their own states (texture, transform) while being able to use other states that they don't care about (view, shader).

Quote
A lot have been said and everybody has changed his mind at least three times. Maybe it would be a good idea to make a quick recap of which ideas seem good so far.

Yup. So far, I'm still on the same solution as in my very first post.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 16, 2011, 05:45:56 pm
Quote from: "Laurent"
That my point: high-level objects can set their own states (texture, transform) while being able to use other states that they don't care about (view, shader).

That's what we have been talking about :lol:

Quote from: "Laurent"
In fact, if all we see for high-level objects is 'object.Draw(window)', I think it's already clear enough that this won't change global states.

So I think this is good enough, go for it. I feel like we have been talking in circles.
Title: The new graphics API in SFML 2
Post by: Laurent on September 16, 2011, 05:51:07 pm
:lol:

So:
Code: [Select]
sf::Sprite sprite;
sprite.SetTexture(...);
sprite.SetPosition(...);

window.SetTexture(...);
window.SetTransform(...);
window.SetShader(...);

window.Draw(sprite); // uses its own texture, transform and the global shader
window.Draw(mesh); // uses global texture, transform and shader

:?:
Title: The new graphics API in SFML 2
Post by: danman on September 17, 2011, 12:09:57 am
I agree :)
Title: The new graphics API in SFML 2
Post by: gsaurus on September 17, 2011, 12:39:35 am
Either target.draw(object) or object.draw(target), do as it is best for SFML.
Title: The new graphics API in SFML 2
Post by: Zinlibs on September 17, 2011, 12:52:36 am
I agree too :D
Title: The new graphics API in SFML 2
Post by: Laurent on September 17, 2011, 09:24:44 am
Great.

Now we can focus on other questions, such as: should high-level objects have their own transform, and keep the same functions as now (Set/Get Position/Rotation/Scale/Origin)? If so, how would one make a sprite relative to a parent object, ie. multiply its own transform by it before passing it to the render target?
Title: The new graphics API in SFML 2
Post by: Groogy on September 17, 2011, 10:54:20 am
Add further functions, instead of having to GetTransform and SetTransform on the render target you have a MultiplyTransform, like how OpenGL have. Or you have PopTransform and PushTransform.
Title: The new graphics API in SFML 2
Post by: otibom on September 17, 2011, 12:28:03 pm
Quote from: "Laurent"

If so, how would one make a sprite relative to a parent object, ie. multiply its own transform by it before passing it to the render target?


Is this a scene graph ?
Title: The new graphics API in SFML 2
Post by: Groogy on September 17, 2011, 12:39:46 pm
No he's talking about the relationship of spaces trough matrixes/transforms.

For instance if we go from object space to world space we multiply by the object's transformation but if we want to go from world space to object space we use the inverse of the matrix.
Title: The new graphics API in SFML 2
Post by: luiscubal on September 17, 2011, 01:34:58 pm
Quote
Add further functions, instead of having to GetTransform and SetTransform on the render target you have a MultiplyTransform, like how OpenGL have. Or you have PopTransform and PushTransform.

Assuming both would have their own transforms(which I'm not 100% sure is the best approach), maybe SetTransformMode(enum TransformMode), where TransformMode can be Inherit, Override or Multiply?

I also feel tempted to suggest not having a global transform at all, and instead let only meshes, sprites, etc. have transforms, though I admit it might not be the simplest-to-use approach.
Title: The new graphics API in SFML 2
Post by: Nexus on September 18, 2011, 11:57:46 am
Argh, I knew I would miss the most interesting discussion :D


Quote from: "Laurent"
BlendMode, Transform and View should always be handled by value (copy), whereas Texture and Shader should be handled by reference. To make it clear, the first three will be passed as const references and the last two will always be passed as const pointer to functions that use them.
The pointers are a good way to make clear that the arguments are referenced after the call and no temporaries are passed, but you should be careful that you don't mix two code styles. Until now, pointers in SFML interfaces imply the possibility of being NULL.


Quote from: "Laurent"
Now we can focus on other questions, such as: should high-level objects have their own transform, and keep the same functions as now (Set/Get Position/Rotation/Scale/Origin)? If so, how would one make a sprite relative to a parent object, ie. multiply its own transform by it before passing it to the render target?
Would the high-level objects also provide set/get functions for the transform itself? Then one could do this:
Code: [Select]
sf::Sprite sprite;
sf::Transform tf = sprite.GetTransform();
sprite.SetTransform(tf * other);

In principle, the interface is unnecessarily big with SetPosition() etc., but the above code is too unconvenient to be the standard way of positioning objects. Another option are free functions, even if you don't seem to like them too much in SFML ;)
Code: [Select]
sf::SetPosition(sprite, pos);
// semantically equivalent to the following, but optimizations are possible:
sf::Transform tf = sprite.GetTransform();
tf.SetTranslation(pos);
sprite.SetTransform(tf);

The big advantage is, you can write this function as a template and it works with all positionable entities. Plus, it can be overloaded for other classes, even ones not part of SFML. Member functions either need a common base class like sf::Drawable, or produce a huge code duplication.


By the way, I have read the thread and have tried to reconstruct the proposals and their implications. But I consider this topic quite complex and I fear that some consequences are only visible when experimenting around with them. So I would appreciate if you left the users some time to test the new API after you have a first working draft, instead of releasing SFML 2 immediately :)
Title: The new graphics API in SFML 2
Post by: Laurent on September 18, 2011, 12:35:20 pm
Quote
The pointers are a good way to make clear that the arguments are referenced after the call and no temporaries are passed, but you should be careful that you don't mix two design policies in SFML. Until now, pointers in SFML interfaces imply the possibility of being NULL.

That's another reason why I need pointers: NULL means no texture/shader.

Quote
Would the high-level objects also provide set/get functions for the transform itself?

It would be the most flexible solution, but SetTransform would conflict with other functions. What happens if you call SetPosition and then SetTransform?

Quote
In principle, the interface is unnecessarily big with SetPosition() etc.

Really? I think that being able to set/get the transformation components individually is what makes it simple. Would you suggest to remove or simplify this interface?

Quote
Another option are free functions, even if you don't seem to like them too much in SFML
[...]
The big advantage is, you can write this function as a template and it works with all positionable entities. Plus, it can be overloaded for other classes, even ones not part of SFML. Member functions either need a common base class like sf::Drawable, or produce a huge code duplication.

But it doesn't work ;)
The interface based on Position/Rotation/Scale is not equivalent to manipulating a sf::Transform directly. sf::Transform accumulates all the transformations that you apply to it, while Position/Rotation/Scale are stored separately, and combined always in the same order. This is less flexible but more convenient.
Also, storing components separately allows to write getters for them. With a sf::Transform alone, you can't get them back (in fact you could get something but it wouldn't always be the same components that you initially set).

Quote
So I would appreciate if you left the users some time to test the new API after you have a first working draft, instead of releasing SFML 2 immediately

Of course! I'm aware that the new API will need to be tested, and probably modified before the final release.
There will always be a release candidate before the final 2.0 release.
Title: The new graphics API in SFML 2
Post by: Groogy on September 18, 2011, 01:11:25 pm
Quote from: "Laurent"
Quote
The pointers are a good way to make clear that the arguments are referenced after the call and no temporaries are passed, but you should be careful that you don't mix two design policies in SFML. Until now, pointers in SFML interfaces imply the possibility of being NULL.

That's another reason why I need pointers: NULL means no texture/shader.


Well the same could be achieved by using the concept of Null Objects cant it? And might be an option for you if you don't like pointers.
Title: The new graphics API in SFML 2
Post by: Laurent on September 18, 2011, 02:48:32 pm
Quote
Well the same could be achieved by using the concept of Null Objects cant it? And might be an option for you if you don't like pointers.

This is not an option here. I already thought about special objects such as Texture::None and Shader::None, but because of the current implementation I can't have global Texture or Shader instances inside SFML. I could use new types and overload SetTexture/SetShader, but that would make the API a little more complicated than it should.
Unless you were suggesting something different.

Anyway, I don't like pointers in public API but I think it's necessary to use them here to make a difference between states that are handled by value and states that are handled by reference.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 18, 2011, 03:01:43 pm
Quote from: "Laurent"
I think that being able to set/get the transformation components individually is what makes it simple.

Definitely.

Quote
Position/Rotation/Scale are stored separately, and combined always in the same order. (...) With a sf::Transform alone, you can't get them back

Thus I guess a SetTransform would just bring confusion. Though there may be constructors or some kind of reset/create function taking a Transform. A const GetTransform may make sense too.
So to combine a sprite with some transform it can be achieved by a call to GetTransform, combine it, and remake the sprite with it.


Quote
Argh, I knew I would miss the most interesting discussion :D

I wondered where you were  :lol:
Title: The new graphics API in SFML 2
Post by: Nexus on September 18, 2011, 03:25:38 pm
Quote from: "Laurent"
That's another reason why I need pointers: NULL means no texture/shader.
Then it's perfectly ok :)


Quote from: "Laurent"
But it doesn't work ;)
The interface based on Position/Rotation/Scale is not equivalent to manipulating a sf::Transform directly. sf::Transform accumulates all the transformations that you apply to it, while Position/Rotation/Scale are stored separately, and combined always in the same order.
Ah, you are right. So, I see the following possibilities:
Anyway, do you already have concrete ideas how high-level objects and sf::Mesh interact? Just private aggregation? Or is the mesh part of the high-level object's public interface?
Title: The new graphics API in SFML 2
Post by: Laurent on September 18, 2011, 03:59:10 pm
Quote
Anyway, do you already have concrete ideas how high-level objects and sf::Mesh interact? Just private aggregation? Or is the mesh part of the high-level object's public interface?

I think it would be a bad idea to mix high-level functions with the low-level ones (sf::Mesh). High-level objects hide the sf::Mesh interface behind their own, simpler functions. It wouldn't make sense to provide both.
Title: The new graphics API in SFML 2
Post by: luiscubal on September 18, 2011, 05:09:56 pm
There's a forth option:
To have a SetTransformCombinationMode(pick better name), to choose which(or what combination) of transforms should be used. But this might even add further to the confusion.
Another variant of this is EnableHighLevelTransforms(again, pick better name).
Title: The new graphics API in SFML 2
Post by: Laurent on September 18, 2011, 06:03:55 pm
The point of providing high-level classes is to keep the same simplicity as before. Trying to make them as flexible as the low-level API doesn't make sense in my opinion. So the third option looks good to me ;)
Title: The new graphics API in SFML 2
Post by: Nexus on September 18, 2011, 11:12:22 pm
That sounds reasonable. Something came to my mind that isn't very relevant in the context of this discussion, but for the library developer: There is still a lot of code duplication (getters, absolute setters and relative setters for each of the transformations in each high-level object).

And to avoid the loss of track, I try to sum up which class holds which public properties (along with some name suggestions :P), please correct mistakes:

Vertex (Point)
- Position
- Color
- TexCoords

VertexArray (Mesh)
- Dynamic array of Vertex elements
- Geometric primitive (Triangle, Quad, ...)

RenderTarget
- View
- Texture
- Shader
- Transform
- BlendMode

High-level object
- Position
- Rotation
- Scale
- Origin
- Color
- Specific properties (e.g. sub-rect at sf::Sprite)
Title: The new graphics API in SFML 2
Post by: Laurent on September 19, 2011, 08:01:02 am
Perfect ;)

I think I'll create a Drawable base class, but it would only define a virtual Draw function, so that people can write window.Draw(object), as well as a ??? class that defines the transformation stuff (position, rotation, scale, ...). sf::Mesh would inherit Drawable, high-level objects would inherit both, and user classes would have the choice.

A detail about "origin": I don't think that it was used a lot as the origin of translation and scaling, therefore I was thinking about changing it to "rotation center", which would remove all the confusion about it.
Title: The new graphics API in SFML 2
Post by: Nexus on September 19, 2011, 11:08:18 am
Quote from: "Laurent"
as well as a ??? class that defines the transformation stuff (position, rotation, scale, ...).
Do you have something in mind like I did here (http://www.bromeon.ch/thor/v1.1/doc/_attributes2_d_8hpp.html), but in one class, maybe sf::Transformable?

Quote from: "Laurent"
A detail about "origin": I don't think that it was used a lot as the origin of translation and scaling, therefore I was thinking about changing it to "rotation center", which would remove all the confusion about it.
From my own experience, I used it a lot for translation. It provides an easy way to align objects properly. For example to refer to right-upper corner instead of the left-upper one, if the object must be positioned relative to an object right from it.
Title: The new graphics API in SFML 2
Post by: Laurent on September 19, 2011, 11:22:32 am
Quote
Do you have something in mind like I did here, but in one class, maybe sf::Transformable?

Absolutely. The "Transformable" name would be perfect as a base class, but I want it to be usable by aggregation as well (it will have no virtual function). Any idea?

Quote
From my own experience, I used it a lot for translation. It provides an easy way to align objects properly. For example to refer to right-upper corner instead of the left-upper one, if the object must be positioned relative to an object right from it.

You're right. But I'd really like to make it less confusing, there are too many threads about this on the forum.
Title: The new graphics API in SFML 2
Post by: Spidyy on September 19, 2011, 07:22:55 pm
Quote
A detail about "origin": I don't think that it was used a lot as the origin of translation and scaling, therefore I was thinking about changing it to "rotation center", which would remove all the confusion about it.


I think it is often used for the scale, particularly to center the scaling of the text in scaling effects. Origin is still the best name for me.
Title: The new graphics API in SFML 2
Post by: Groogy on September 19, 2011, 07:57:13 pm
I'm not really interested in this myself but there might be people out there who are. Will geometry shader come with the shader changes? Just found out some good use cases for it today in 2D applications. Though it's more a way to optimize repetive rendering I guess by minimizing bandwith. If interested I can write more what I am thinking about and some math behind it.
Title: The new graphics API in SFML 2
Post by: Laurent on September 19, 2011, 08:32:21 pm
Quote
I think it is often used for the scale, particularly to center the scaling of the text in scaling effects. Origin is still the best name for me.

Hmm ok, so I won't touch that.

Quote
Will geometry shader come with the shader changes?

No, it's too recent.
Title: The new graphics API in SFML 2
Post by: Lokk on September 19, 2011, 09:51:02 pm
Quote
maybe sf::Transformable?

or sf::Spatial ?
Title: The new graphics API in SFML 2
Post by: gsaurus on September 20, 2011, 12:06:35 am
Quote from: "Laurent"
sf::Mesh would inherit Drawable, high-level objects would inherit both, and user classes would have the choice.

Hm inheritance :roll: ... Sometime in the past I had a problem with the restrictions caused by the drawables inheritance. If I still remember I had an abstract CompositeDrawable derived from sf::Drawable, and at some point I wanted a leaf deriving from CompositeDrawable and from sf::Sprite, causing a diamond problem which I couldn't solve.

As for the center, I used it a lot too, it's very handy. Particularly, if you implement flip operations on Sprite, do it around the center. But I think Scale/SetScale is enough, I'd discard the old flip operations (negative scale to flip)
Title: The new graphics API in SFML 2
Post by: Laurent on September 20, 2011, 08:37:15 am
Quote
Sometime in the past I had a problem with the restrictions caused by the drawables inheritance. If I still remember I had an abstract CompositeDrawable derived from sf::Drawable, and at some point I wanted a leaf deriving from CompositeDrawable and from sf::Sprite, causing a diamond problem which I couldn't solve.

Inheriting from sf::Drawable means that you define your own drawing.
Inheriting from sf::Sprite means that you use a high-level objects that has its own drawing.
-> So what does it mean to inherit from both?

The new sf::Drawable class will only define the Draw virtual function, all the transformation stuff will be in a new class. Maybe this new design would solve your problem?
Title: The new graphics API in SFML 2
Post by: Laurent on September 20, 2011, 08:39:26 am
Quote
Do you have something in mind like I did here, but in one class, maybe sf::Transformable?

I can see that you have no function to set X or Y alone (in Positionable and Scalable). I was thinking about removing these functions in SFML, what do you think about it?

And also... Point/Mesh or Vertex/VertexArray? :D
Title: The new graphics API in SFML 2
Post by: Nexus on September 20, 2011, 11:42:09 am
Quote from: "Laurent"
You're right. But I'd really like to make it less confusing, there are too many threads about this on the forum.
I think this is only possible when storing 3 separate origins for translation, rotation and scale. But it would probably bloat the interface too much (one hardly needs to set all three centers). So, maybe this should belong to the category "full customization with low-level API".

Quote from: "Laurent"
I can see that you have no function to set X or Y alone (in Positionable and Scalable). I was thinking about removing these functions in SFML, what do you think about it?
Hm, difficult to say. After a short search for "SetX" and "SetY" in my main projects, it seems like I haven't used them a single time. Technically, they are not necessary either, since one can easily write a free function to set them. Otherwise -- strictly following the convenience/consistency argument -- you should also add SetOriginX/Y() and maybe even SetColorR/G/B/A().

In my opinion, you can give it a try, you also encourage vector-based instead of component-based operations. And if it turns out to be totally unacceptable, you can still add the functions -- better than the other way around :)

Quote from: "Laurent"
And also... Point/Mesh or Vertex/VertexArray? :D
I prefer Vertex/VertexArray, since it describes the functionality more clearly. Also, I associate "mesh" with 3D models...
Title: The new graphics API in SFML 2
Post by: Laurent on September 20, 2011, 11:52:19 am
Quote
So, maybe this should belong to the category "full customization with low-level API".

I think I'll just keep it as it is now: a single origin for all transformations.

Quote
In my opinion, you can give it a try, you also encourage vector-based instead of component-based operations. And if it turns out to be totally unacceptable, you can still add the functions -- better than the other way around

Yep :)

Quote
I prefer Vertex/VertexArray, since it describes the functionality more clearly.

But do these words make sense for someone who is totally new to graphics rendering?

Quote
Also, I associate "mesh" with 3D models...

Me too. But again, what about people with no background in graphics programming?
Title: The new graphics API in SFML 2
Post by: Nexus on September 20, 2011, 12:04:55 pm
I see it like this: The low-level API of SFML requires some knowledge anyway, common terms alone are not enough if the theory behind them is unknown. For example, a beginner might understand "Point", but gets stuck at "TexCoords" because he doesn't know about texture mapping. Apart from that, I doubt "Mesh" is such a self-explanatory notion, at dict.cc I get about 10 translations none of which is related to graphics programming.

The documentation has to be read in every case, so you could spend one phrase to explain what a vertex is. The advantage is that you stick to common terms and don't confuse people who already have some graphics programming background. And the relation between vertices and vertex arrays is obvious.
Title: The new graphics API in SFML 2
Post by: Laurent on September 20, 2011, 12:24:37 pm
Quote
I doubt "Mesh" is such a self-explanatory notion, at dict.cc I get about 10 translations none of which is related to graphics programming.

In french the translation is perfect. And I already got positive feedback on this name:
Quote
Other than sf::VertArray I don't think you can get much more descriptive than sf::Mesh.  Although "mesh" tends to suggest (to me) three dimensions.

Quote
sf::Mesh fits perfectly as the name.


Other than that, your points are all valid ;)

However, Vertex and VertexArray could suggest 3D as well. In fact the perfect name would be something that implies 2D. But I don't think it exists.
Title: The new graphics API in SFML 2
Post by: gsaurus on September 20, 2011, 01:01:52 pm
I like Vertex and Mesh. Vertex instead of Point because Point suggests a location in world space. Mesh instead of VertexArray because it's more than a vertex array, it has texture coordinates associated and looks more like a matrix. I think mesh fits perfectly.


Quote
what does it mean to inherit from both?

You know, extension of families of classes. For some reason I wanted to add new functionality to the whole family. I made it in one way or another anyway.
Well since the new sf::Drawable is just an interface that shouldn't be a problem, but where will you put the code that is common to Sprite/Text/etc?
Title: The new graphics API in SFML 2
Post by: Laurent on September 20, 2011, 01:19:26 pm
Quote
but where will you put the code that is common to Sprite/Text/etc?

Transformations will be defined in the Transformable class.
Color will be duplicated in every class, because it can't be implemented in a generic way anymore (I have to change the color of every vertex).
Blend mode will stay a global state.
Title: The new graphics API in SFML 2
Post by: Spidyy on September 20, 2011, 02:50:10 pm
Quote from: "Laurent"
Quote
Do you have something in mind like I did here, but in one class, maybe sf::Transformable?

I can see that you have no function to set X or Y alone (in Positionable and Scalable). I was thinking about removing these functions in SFML, what do you think about it?

And also... Point/Mesh or Vertex/VertexArray? :D


Function to set X and Y alone are a nice mean to shorten the code. I mean, I prefer doing a little SetX(val); instead of SetPosition(sf::Vector2(value, GetPosition().Y));

Also, Mesh and Vertex. Thoses are names used in 3D design and creation. Even in a 2D space, a vertex is a vertex. You could add a typename Point for thoses unfamiliar with Vertex, but for the beginners, I think it is a good thing to initiate them with standard naming. Same reasoning with sf::Transform instead of sf::Spatial.
Title: The new graphics API in SFML 2
Post by: Laurent on September 20, 2011, 03:03:25 pm
Quote
Function to set X and Y alone are a nice mean to shorten the code. I mean, I prefer doing a little SetX(val); instead of SetPosition(sf::Vector2(value, GetPosition().Y));

There will still be SetPosition(x, y) ;)

Quote
Same reasoning with sf::Transform instead of sf::Spatial

sf::Transform exists and won't change. sf::Spatial was suggested as a replacement to sf::Transformable.
Title: The new graphics API in SFML 2
Post by: Mikademus on September 22, 2011, 12:59:50 pm
Another issue is that the current set of blend modes is inadequate. Our application makes heavy use of particle effects, and only alphablend, additive and multiply blend modes are insufficient. Primarily we need the subtractive mode, but some effects we are importing also needs screen and interpolation blending. A very common need out in the wild is also a premultiplied alpha mode.

Personally, I think that the best way to handle this is by:
1) Adding at least the Subtractive, Screen and perhaps also the PremultAlpha modes to the enum, and
2) Allow custom blend modes by providing a function where the user can specify the glBlendFunc arguments himself.

This will allow keeping the API simple while allowing advanced users to do what they need to.


Resources:
* Earlier thread (http://www.sfml-dev.org/forum/viewtopic.php?p=6878&sid=d561446659ef92fb5c6e43b2341516b2) with some pictures a search turned up.
* Parameter values for some additional modes on jMonkeyEngine's blend api docs (http://jmonkeyengine.org/javadoc/com/jme3/material/RenderState.BlendMode.html).
Title: The new graphics API in SFML 2
Post by: Laurent on September 22, 2011, 01:26:36 pm
Thanks for your feedback, and for finding these useful resources.

Blend modes definitely need some improvements and more flexibility, I'll try to think about it and submit some ideas, maybe in a dedicated thread.
Title: The new graphics API in SFML 2
Post by: Laurent on September 23, 2011, 03:36:20 pm
I was thinking about renaming "SubRect" in sf::Sprite. Would "TextureArea" or TextureRegion" be better?
Title: The new graphics API in SFML 2
Post by: thePyro_13 on September 23, 2011, 04:03:15 pm
I don't read TextureArea or TextureRegion as more descriptive than SubRect.

Perhaps incorporating the word 'crop' would be more descriptive, that's what is used in image editing programs to describe essentially the same function as SubRect.
Title: The new graphics API in SFML 2
Post by: Laurent on September 23, 2011, 04:05:41 pm
Quote
Perhaps incorporating the word 'crop' would be more descriptive, that's what is used in image editing programs to describe essentially the same function as SubRect.

Can "crop" be used as a noun? I thought it was only a verb, with no corresponding noun.
Title: The new graphics API in SFML 2
Post by: Nexus on September 23, 2011, 04:14:53 pm
It can, but I spontaneously think of cereals when I hear it :)
And "crops" is probably more widespread, at least according to my experience...

It actually isn't expressive at all, one has to know the term to understand it. That's why I prefer something like TextureArea (or TextureRect?).
Title: The new graphics API in SFML 2
Post by: Lo-X on September 23, 2011, 05:25:34 pm
That make me think... It is possible to add a method sf::Drawable::GetCollisionRect(sf::View&) ? which return a rect but already with proper coordinates ? Not too difficult to do it actually but, I ask... :p
Title: The new graphics API in SFML 2
Post by: Laurent on September 23, 2011, 05:34:28 pm
sf::Drawable will disappear. And what would the view argument be used for? Collisions are usually computed in global coordinates, while views are used only for displaying things in a target. Moreover, a rectangle in global coordinates can be rotated, which SFML doesn't support.
Title: The new graphics API in SFML 2
Post by: Mikademus on September 23, 2011, 07:07:53 pm
"sf::Drawable will disappear"

That will have a rather huge impact on my codebase. Currently there are functions that works along this way:

Code: [Select]

void func( RenderTarget &rTarget )
{
Drawable *pDrawable = 0;

switch (something)
{
   case st1: pDrawable = &mySprite; break;
   case st2: pDrawable = &myCircle; break;
   case st3: pDrawable = &myRectagle; break;
}

pDrawable->SetPosition( myPos );
pDrawable->SetRotation( myRot );
pDrawable->SetColor( myCol );

rTarget.Draw( pDrawable );
}


How will the removal of th Drawable interface affect my code?
Title: The new graphics API in SFML 2
Post by: Nexus on September 23, 2011, 07:14:32 pm
Laurent also said:
Quote from: "Laurent"
I think I'll create a Drawable base class, but it would only define a virtual Draw function, so that people can write window.Draw(object)
I understand his latest statement in the way that sf::Drawable disappears in its current state (with all the transformations).

And in general, templates are a possible alternative to dynamic polymorphism.
Title: The new graphics API in SFML 2
Post by: Laurent on September 23, 2011, 07:16:27 pm
Quote
That will have a rather huge impact on my codebase

I know, and you're not the only one ;)
The current API is too limited so it needs a complete redesign. I'll try to keep high-level classes as close to their current version as possible, but abstractions such as sf::Drawable won't work anymore.

So your function would be a little more verbose, but depending what you want to achieve their may be better strategies with the new API.
Title: The new graphics API in SFML 2
Post by: Nexus on September 23, 2011, 07:20:22 pm
Quote from: "Laurent"
The current API is too limited so it needs a complete redesign. I'll try to keep high-level classes as close to their current version as possible, but abstractions such as sf::Drawable won't work anymore.
Now you confuse me :D

I don't expect a definitive statement, but do you currently tend to provide a sf::Drawable class (just as drawing interface) or rather not? If not, how are objects drawn? sprite.Draw(window)? Personally, I'd like a sf::Drawable class for those abstraction reasons.
Title: The new graphics API in SFML 2
Post by: Hiura on September 23, 2011, 07:26:22 pm
Quote from: "Laurent"
I was thinking about renaming "SubRect" in sf::Sprite. Would "TextureArea" or TextureRegion" be better?
TextureArea sounds better than TextureRegion because region doesn't always have fixed boundaries.
Title: The new graphics API in SFML 2
Post by: Laurent on September 23, 2011, 07:29:00 pm
Sorry for the confusion :D

I'm sticking with the latest conclusions:
Code: [Select]
class Drawable
{
private :

    friend class RenderTarget;

    virtual void Draw(RenderTarget&) = 0;
};

class Transformable
{
    position / rotation / scale / origin
};

class Sprite : public Drawable, public Transformable
{
    texture, texture area, color
};
Title: The new graphics API in SFML 2
Post by: gsaurus on September 23, 2011, 08:01:39 pm
Quote from: "Hiura"
TextureArea sounds better than TextureRegion because region doesn't always have fixed boundaries.

Area also does not suggest a rectangular area. Maybe TextureRect
Title: The new graphics API in SFML 2
Post by: Mikademus on September 23, 2011, 09:10:23 pm
SourcePixels
Title: The new graphics API in SFML 2
Post by: Nexus on September 23, 2011, 09:36:23 pm
Quote from: "Laurent"
I'm sticking with the latest conclusions:
Okay, I already thought about an own Drawable wrapper that would store high-level objects via type erasure to allow abstraction nevertheless :P

Quote from: "Laurent"
Code: [Select]
class Drawable
{
private :

    friend class RenderTarget;

    virtual void Draw(RenderTarget&) = 0;
};
So, Draw() actually replaces the old Render()?

Quote from: "Hiura"
Quote from: "Laurent"
I was thinking about renaming "SubRect" in sf::Sprite. Would "TextureArea" or TextureRegion" be better?
TextureArea sounds better than TextureRegion because region doesn't always have fixed boundaries.
And TextureRect sounds better than TextureArea because it indicates a rectangular area. Plus, it is closer to the existing term SubRect, making code porting easier.

Quote from: "Mikademus"
SourcePixels
Not good in my opinion, since the sub-rectangle doesn't store any pixels.
Title: The new graphics API in SFML 2
Post by: Mikademus on September 23, 2011, 10:17:29 pm
Quote from: "Nexus"
Quote from: "Mikademus"
SourcePixels
Not good in my opinion, since the sub-rectangle doesn't store any pixels.

SourcePixelRect
SourcePixelArea

You can't get more descriptive and explanatory than that.
Title: The new graphics API in SFML 2
Post by: Hiura on September 23, 2011, 10:54:10 pm
Well, if we have sf::Texture it's more consistent to have TextureSomething than SourcePixelSomething.

Now about the "something"-part, like Nexus said "rect" seems to fit the job for sprites as they are rectangular. But what about shapes ? If shapes also have texture ( ? ) then rect doesn't fit and having two different names can be confusing. So if they have texture then "area" seems better to me, otherwise I agree with TextureRect.
Title: The new graphics API in SFML 2
Post by: Laurent on September 23, 2011, 11:07:08 pm
TextureRect is ok for me.

Quote
Now about the "something"-part, like Nexus said "rect" seems to fit the job for sprites as they are rectangular. But what about shapes ? If shapes also have texture ( ? ) then rect doesn't fit and having two different names can be confusing. So if they have texture then "area" seems better to me, otherwise I agree with TextureRect.

If sf::Shape had a SetTextureSomething which is not a rectangle, I don't know what it could be because SFML has nothing more complicated than rectangles ;)

I still have to decide what sf::Shape will become. It will probably change a lot.
Title: The new graphics API in SFML 2
Post by: Groogy on September 24, 2011, 04:40:29 pm
Well it could still be a rectangle but when adding points to the shape you also specify where in the texture rectangle this point is. Normal UV mapping.
Title: The new graphics API in SFML 2
Post by: Laurent on September 24, 2011, 05:12:28 pm
Quote
Well it could still be a rectangle but when adding points to the shape you also specify where in the texture rectangle this point is. Normal UV mapping.

So you would give points inside a sub-rectangle of the texture? Why not just points inside the texture directly?
Title: The new graphics API in SFML 2
Post by: Groogy on September 24, 2011, 05:18:15 pm
Because then setting a sub rect for a shape would have no purpose :P
Also would make it possible to have sprite sheets with shapes I guess. I mean it wouldn't be a hazzle if you don't want to use t as it would only default to the whole texture size.
Title: The new graphics API in SFML 2
Post by: Canadadry on September 30, 2011, 09:16:43 pm
I've got an idea of a possible pattern for hiding vertex concept. This is just the beginning of what that could do. And just for the public side not for implementation.

What if we keep the old architecture (just to simplified my explanation) and then add 4 functions to the drawable class
Code: [Select]
beginStaticDrawing
endStaticDrawing
beginDynamicDrawing
endDynamicDrawing


This two couples of functions allow the user to define complicated sprite this way

Code: [Select]
myTileMap.beginStaticDrawing();
for(int i=0;i<myTile.size();i++)
    myTiles[i].draw();
myTileMap.endStaticDrawing();


Then I just need to to call draw function of myTileMap to draw the entire tile map. It act like a dispay list.

With the other function, you will build another kind of list which will allow you to move (or else ..) some of the tile which will update the data behind for the next draw.

I think this approach should allow basic user to build display list or vertex array without knowing anything of it.  
What do you think of it ?
Title: The new graphics API in SFML 2
Post by: Laurent on September 30, 2011, 10:25:02 pm
I had already thought about such a "bridge" between low-level vertex arrays and high-level classes. We can also call it "explicit batching".

But there are some problems to solve. To put several entities in the same vertex array, they must share the same texture and the same type of primitives.

This means that you can't put texts of different sizes/styles/fonts in the same batch, or sprites with different textures, or shapes. Or any combination of these classes of course. This new feature would be very limited.

But that's definitely something to keep in mind, and after the basics of the new API are well defined I'll probably think about batching again.
Title: The new graphics API in SFML 2
Post by: luiscubal on October 01, 2011, 01:21:57 am
I believe some graphics cards support using multiple textures at once. It would be neat to have a SFML method like "GetMaximumNumberOfSimultaneousTextures"(with a better name). Then one would use this number to use multiple textures at once and improve batching. Wouldn't this improve the performance?

Perhaps preferably, SFML could automatically batch things internally, so all this would merely be an implementation detail and the programmer would be blissfully unaware of any batching at all.

So, if a GPU only supports one texture at a time.

1. UseTexture1
2. UseTexture1
3. UseText1
4. UseTexture2

In the above case, SFML would automatically batch 1 and 2 together, but not 3 and 4.

P.S: I know that I've suggested multiple textures support on Mesh before, but here what I have in mind is slightly different. Instead of using multiple textures for improved visuals, it'd be for improved speed. I'm not even considering how to implement this stuff in terms of Meshes.
Title: The new graphics API in SFML 2
Post by: Laurent on October 01, 2011, 10:28:41 am
Quote
I believe some graphics cards support using multiple textures at once. It would be neat to have a SFML method like "GetMaximumNumberOfSimultaneousTextures"(with a better name). Then one would use this number to use multiple textures at once and improve batching. Wouldn't this improve the performance?

You can't use multi-texturing like this. Anything that is rendered always uses all the texture units. You can't assign specific texture units to different parts of a vertex array, and render the whole thing in one call.

Quote
Perhaps preferably, SFML could automatically batch things internally, so all this would merely be an implementation detail and the programmer would be blissfully unaware of any batching at all.

To be efficient, batching must reorder entities, which means that I must handle their drawing order with an explicit Z value. And that doesn't work well with alpha-blended entities.
Title: The new graphics API in SFML 2
Post by: Canadadry on October 01, 2011, 02:19:05 pm
Quote from: "Laurent"
But there are some problems to solve. To put several entities in the same vertex array, they must share the same texture and the same type of primitives.


That's a shame.... I haven't thought of that....  :(
Title: The new graphics API in SFML 2
Post by: Lee R on October 05, 2011, 03:24:47 am
-1 for "Mesh". In English, the word "Mesh" cannot in any sense represent the notion of a list containing discrete (non-mesh forming) geometry (e.g. a list of quads).

-1 for "Point". I personally predict that users seeing the name "Vertex" along with a brief description of what that means, will be less confused than a seeing a "Point" class/struct containing all manner of data members which are completely unrelated to the notion of a position in space.

+1 for VertexArray (and/or possibly even QuadList, TriangleList .etc with the appropriate interface)

+1 for Vertex.
Title: The new graphics API in SFML 2
Post by: Laurent on October 05, 2011, 08:03:20 am
Quote
-1 for "Mesh". In English, the word "Mesh" cannot in any sense represent the notion of a list containing discrete (non-mesh forming) geometry (e.g. a list of quads).

Correct. But I was thiking it would be ok, because 95% of meshes would truly be meshes; separate primitives would be a specific case -- the only use case that I can see is particles systems.
I don't like VertexArray, it's more an array of primitives (unlike OpenGL, the primitive type is an attribute of the class, it's not given at draw time). However it acts like an array of vertices (operator[] returns a vertex), so... I don't know.
What about sf::Geometry, or sf::Primitives? I guess they are bad too, because of the "array of vertices" semantics.

Quote
-1 for "Point". I personally predict that users seeing the name "Vertex" along with a brief description of what that means, will be less confused than a seeing a "Point" class/struct containing all manner of data members which are completely unrelated to the notion of a position in space.

It is a position in space, with some extra data attached to it.

Quote
+1 for VertexArray (and/or possibly even QuadList, TriangleList .etc with the appropriate interface)

I tried this approach before, but these classes would have to return a Quad/Triangle with their operator[], which is not very convenient.
Title: The new graphics API in SFML 2
Post by: Lee R on October 05, 2011, 04:12:22 pm
Quote from: "Laurent"
Quote
-1 for "Mesh". In English, the word "Mesh" cannot in any sense represent the notion of a list containing discrete (non-mesh forming) geometry (e.g. a list of quads).

Correct. But I was thiking it would be ok, because 95% of meshes would truly be meshes;

Then perhaps you would prefer 'MeshMostlyExceptWhenItsNot' ;)


Quote from: "Laurent"

I don't like VertexArray, it's more an array of primitives (unlike OpenGL, the primitive type is an attribute of the class, it's not given at draw time). However it acts like an array of vertices (operator[] returns a vertex), so... I don't know.
What about sf::Geometry, or sf::Primitives? I guess they are bad too, because of the "array of vertices" semantics.

That would seem to argue in favour of QuadList, TriangleList etc. I'd also like to point out the amount of times you quite naturally used the word "vertex" there ;)


Quote from: "Laurent"
Quote
-1 for "Point". I personally predict that users seeing the name "Vertex" along with a brief description of what that means, will be less confused than a seeing a "Point" class/struct containing all manner of data members which are completely unrelated to the notion of a position in space.

It is a position in space, with some extra data attached to it.

No. It is a vertex which has a position in space. For instance, it wouldn't be unheard of to see something like:

Code: [Select]

struct Point
{
    float x;
    float y;
};

struct Vertex
{
    Point position;
    // ...
};


Quote from: "Laurent"
Quote
+1 for VertexArray (and/or possibly even QuadList, TriangleList .etc with the appropriate interface)

I tried this approach before, but these classes would have to return a Quad/Triangle with their operator[], which is not very convenient.

I had actually thought it would have been more convenient. It would certainly make the tile-sheet code you presented earlier a lot more readable. I'm not at all attached to those structures, but I wonder what exactly you thought would be the inconvenience? dealing structure padding or?
Title: The new graphics API in SFML 2
Post by: Laurent on October 05, 2011, 04:27:55 pm
Quote
No. It is a vertex which has a position in space. For instance, it wouldn't be unheard of to see something like
[...]

Yes of course. If it was just me, the code would already look like this one.
I was just trying to find a word that would sound more "natural" to beginners (and generally non-3D people), but I guess that it doesn't exist.

I'll probably consider using Vertex/VertexArray again.

Quote
I had actually thought it would have been more convenient. It would certainly make the tile-sheet code you presented earlier a lot more readable. I'm not at all attached to those structures, but I wonder what exactly you thought would be the inconvenience? dealing structure padding or?

Padding is one thing, but I just need to find the specific #pragma or whatever for every supported compiler.

I don't like the way the code would be transformed:
Code: [Select]
vertices[i * 4].Position = ...;

// vs

quads[i].p0.Position = ...;

(I don't like "p0" nor "p[0]" or whatever to name the four points of the quad -- but anything cleaner would be longer)

Moreover, it means that the type of primitives must be chosen at compile time, and cannot be changed at runtime. I don't know if it's annoying, though.

On the positive side, I could add helper functions:
Code: [Select]
quads[i].SetFromTextureRect(sf::IntRect(...));
// 8 lines of code into 1

(just like a sprite)
Title: The new graphics API in SFML 2
Post by: Lee R on October 05, 2011, 05:18:06 pm
I wont be putting much effort into arguing for QuadList et al, since I share your concern over the possible annoyance of static typing there. I suppose people who really care about such things can write some sort of QuadView structure over a VertexArray or similar.
Title: The new graphics API in SFML 2
Post by: Mikademus on October 07, 2011, 05:35:29 pm
Quote from: "Laurent"
Quote
-1 for "Point". I personally predict that users seeing the name "Vertex" along with a brief description of what that means, will be less confused than a seeing a "Point" class/struct containing all manner of data members which are completely unrelated to the notion of a position in space.

It is a position in space, with some extra data attached to it.


Sure sounds like a vertex to me.

As you said, there is no a priori understandable terminology for this. Just go with the industry standard. The beginners will learn and you won't frustrate the non-beginners, which is just as important a consideration.
Title: The new graphics API in SFML 2
Post by: Laurent on October 07, 2011, 06:07:22 pm
Ok, sold.
Title: The new graphics API in SFML 2
Post by: laserbeams on October 08, 2011, 03:40:08 am
Quote from: "Laurent"
However, Vertex and VertexArray could suggest 3D as well. In fact the perfect name would be something that implies 2D. But I don't think it exists.

I realise you may be a bit beyond this, and I agree with the usage of vertex, but the only word I can think of that implies 2D would be net or network - but that also implies hollow.

I'm concerned about conflating an array or list of vertexes with something that's displayable as flat or textured polygons.  If I wanted a cloud of points, I'd use a vertex list, but there is none of the inherent grouping needed for face display in the concept of a vertex list, particularly if you intend to allow both tris and quads.  I've only ever seen a straight list of vertexes used to define a triangle strip, because then there is no ambiguity of order.

As a relative newbie, what I'd expect is a "face" object, which could be either a tri or quad, and essentially a tuple (is this the right word?) of several vertexes, perhaps with additional information that the vertexes alone wouldn't encode, like texture.  Would this be too much like a sprite?  Would this -be- a sprite?

I would also expect something like a "shape" object that could hold more complex geometry, but I can think of two ways to go about this.  One would be not much more than a "faceList".  The vertexes, texture coordinates, and textures would already be defined.  I realise this could be very inefficient with multiple textures referenced.  Alternatively "face" objects could leave out the texture, and texture could be a property of the "shape" or "geometry".

The other would be a "vertexList" along with an "indexFaceList", which would be the more traditional approach of referring to indexes in a vertex array for each polygon, so polygons can have shared vertexes (including texture coordinates).  Again, texture and such would be a property of the "shape".

Am I sort of on the right page?

Disclaimer:  I'm pretty new to this.
Title: The new graphics API in SFML 2
Post by: Lee R on October 08, 2011, 08:52:37 pm
Having an array of vertices represent geometry is all about efficiency, since that is what most closely matches the machine model. I haven't seen anything in this thread which would lead me to believe that higher level abstractions wont be provided, so I think your concern is premature at best.
Title: The new graphics API in SFML 2
Post by: heishe on October 17, 2011, 09:53:31 pm
Laurent, do you know how the XNA Framework does batching? I think the way their API works is really nice. There's a class called "SpriteBatcher" that does all the low level stuff for you. The only thing that the user can do (it's optional) is hand over parameters concerning the drawing mode, e.g. blending, sorting by textures and batching that way, etc.

You just hand over sprites/textures and the class does the rest for you.

It's incredibly fast as well. I get about 20000FPS (yes, 20k fps) in a demo where I draw about 100 small rects with three different 16x16 textures on them.

I think that style fits SFML best. The abstraction level where SFML is now (high level but it's very easy to get access to low level stuff) is pretty much perfect, and the SpriteBatcher as a performance boost would be a good addition to that, imo.
Title: The new graphics API in SFML 2
Post by: Laurent on October 18, 2011, 10:33:56 pm
Quote
Laurent, do you know how the XNA Framework does batching? I think the way their API works is really nice. There's a class called "SpriteBatcher" that does all the low level stuff for you. The only thing that the user can do (it's optional) is hand over parameters concerning the drawing mode, e.g. blending, sorting by textures and batching that way, etc.

Batching can be done in SFML, but it would probably be more limited than in XNA. To be efficient, entities have to be reordered, but to do so they must have a depth, so that a different rendering order has no impact on the result.
Anyway, batching will probably come later, as an optimization on top of the new API, if performances require it.
Title: The new graphics API in SFML 2
Post by: Laurent on October 19, 2011, 10:12:13 am
I haven't had a lot of time to work on this lately, but here are some news anyway.

First, I renamed classes to Vertex and VertexArray. If someone tells me that Point/Mesh were better names, I kill him :mrgreen:

The second point is a new concept. I was thinking about changing how render states (transform, texture, shader, blend mode) were managed. Currently, they can be read/written with accessors in sf::RenderTarget, and they are persistent between two calls to Draw.
Code: [Select]
window.SetTexture(texture);

window.SetTransform(transform1);
window.Draw(geometry1);

window.SetTransform(transform2);
window.Draw(geometry2);


I don't like persistent states because when you draw something you never know what value each state has, and you have to overwrite them all to be safe. But you also have to push/pop them so that the parent entity can find its states back if it needs to render other children.

My idea was to get rid of all getters and setters, and instead implement a new class named RenderStates, that would hold the states to use for a drawing operation.

Code: [Select]
class RenderStates
{
    BlendMode blendMode;
    Transform transform;
    const Texture* texture;
    const Shader* shader;
};

class RenderTarget
{
    void Draw(const Drawable& drawable, RenderStates states = RenderStates::Default);
};


States would be forwarded, modified if needed, along the hierarchy of Draw calls:
Code: [Select]
class Sprite : public Drawable, public Transformable
{
    void Draw(RenderTarget& target, RenderStates states)
    {
        states.transform *= GetTransform();
        states.texture = myTexture;
        target.Draw(myVertexArray, states);
    }
};

... and finally applied at the lowest level, when drawing a vertex array
Code: [Select]
class RenderTarget
{
    void Draw(const VertexArray& vertexArray, RenderStates states = RenderStates::Default)
    {
        // apply states
        // render vertex array
    }
};


For convenience, RenderStates will have implicit constructors taking a single state, so that you can write this kind of code:
Code: [Select]
window.Draw(entity, transform);
window.Draw(sprite, shader);
...
Title: The new graphics API in SFML 2
Post by: Nexus on October 19, 2011, 11:58:31 am
A struct sf::RenderStates sounds good, it goes away from the global statemachine (OpenGL style). Is sf::Transform now only stored in sf::RenderTarget, or do the geometries also own such a member?

And sf::Transformable is the mix-in class that provides GetPosition() etc. plus a convenient GetTransform() which is computed on-the-fly? I'm just not sure in which class the GetTransform() call in your code is ;)

But this approach might lead to many OpenGL calls because of state changes. Or do you plan to write some sort of cache to apply state changes only if necessary?
Title: The new graphics API in SFML 2
Post by: Laurent on October 19, 2011, 12:13:04 pm
Quote
Is sf::Transform now only stored in sf::RenderTarget, or do the geometries also own such a member?

What do you mean?
The transform is a render state, so it is defined in sf::RenderStates. Only the Transformable base class has its own transform.
EDIT: indeed, GetTransform() is the computed transform from sf::Transformable ;)

Quote
But this approach might lead to many OpenGL calls because of state changes. Or do you plan to write some sort of cache to apply state changes only if necessary?

With this approach, every call to Draw(VertexArray) will trigger 5 OpenGL calls: one for each state, plus one to send the vertices. It could be a lot, but I hope that with the new API people will create optimized classes that use one big VertexArray instead of multiple sprites.

A render states cache is complicated to implement, because of three problems:
- it's hard to check if a transform is the same as the previous one (several floating point numbers to compare)
- even if a shader or a texture is the same, its internal state may have changed (texture updated, shader parameter changed, ...) so it sill needs to be bound again -- look at the many bugs that it currently causes in sf::Renderer :)
- if people use OpenGL calls in between, it's hard to keep the SFML cache up-to-date; but this can be solved with functions such as SaveGLStates/RestoreGLStates (they will probably change when the new API is ready)
Title: The new graphics API in SFML 2
Post by: Nexus on October 19, 2011, 01:52:07 pm
Maybe a hash could avoid expensive comparisons. But you're right, you shouldn't focus on a riskily optimized renderer cache if you provide the super-fast way via sf::VertexArray :)
Title: The new graphics API in SFML 2
Post by: Laurent on October 20, 2011, 10:30:59 am
The next step will be a redesign of sf::Shape. I don't like its API, and a lot of people don't understand the concept of local points/global position. And the API is going to be definitely bloated if I add support for texturing.

So I was thinking about writing one class for each specific shape (line, triangle, rectangle, circle, star, whatever), inheriting from a common base that provides most of the implementation. Of course, one of them will be sf::ConvexShape so that you can still get the full set of features, like before. And the base class will allow users to create their own type of shape very easily if they want to.

This way, users won't have to deal with local vs global positions anymore: all points will be implicitely created with (0, 0) as their local origin, like sf::Text and sf::Sprite. Only the sf::Transformable functions will be able to move the shape in the 2D scene.
Another benefit is that each class can define its own specific API: circle with radius, line with start/end, etc.

Most of the features will be kept: outline thickness, outline color, fill color (it will be one for the whole shape instead of one per point, but I'll create a new class sf::ColorGradient), and a new feature will be added: texturing.

I think this is a good compromise between simple features and flexibility. People who want very specific shape features can still build their own stuff with a sf::VertexArray.
Title: The new graphics API in SFML 2
Post by: Nexus on October 20, 2011, 04:35:24 pm
Interesting! :)

I don't see the big difference between the base class (let's say sf::Shape) and sf::ConvexShape yet. You write that sf::Shape would allow custom shapes very easily, do you have something concrete in mind? I guess that AddPoint() will only be added in sf::ConvexShape...

And have you already spent some thoughts about the API of sf::ColorGradient?
Title: The new graphics API in SFML 2
Post by: Laurent on October 20, 2011, 04:48:04 pm
Quote
I don't see the big difference between the base class (let's say sf::Shape) and sf::ConvexShape yet.

sf::Shape will define the common properties: outline, colors, texturing, as well as attributes inherited from Transformable and Drawable of course. It will also implement all the boring private stuff: computing the outline, computing the texture coordinates, applying the color gradient if needed, and rendering the geometry.
So sf::Shape's API will be quite useless alone. sf::ConvexShape is the one that will define the powerful API: points position, ... and ... hum ... that's all :lol:

Quote
And have you already spent some thoughts about the API of sf::ColorGradient?

Yep. It will be very simple, so that it can be mapped on any shape, even those with only 4 vertices (= rectangles):
- start color
- end color
- direction (horizontal or vertical)

If I can apply it to other drawables, I'll do it too.
Title: The new graphics API in SFML 2
Post by: Nexus on October 21, 2011, 06:42:22 pm
Quote from: "Laurent"
Yep. It will be very simple
But will it be useful enough? Are there many people needing exactly a vertical or horizontal gradient with 2 colors so that an extra class is justified? Wouldn't one rather use shaders for such features (which allow much more)?

And how does it mix with single sf::Color attributes, will there only a SetColorGradient() and an implicit conversion from sf::Color to sf::ColorGradient? In this case, does extracting a single color (which is probably often used) always look like shape.GetColorGradient().GetFirstColor()?

Sorry for questioning everything ;)
Title: The new graphics API in SFML 2
Post by: Laurent on October 21, 2011, 11:03:13 pm
No, you're totally right. This definitely needs more thinking ;)
Title: The new graphics API in SFML 2
Post by: Mikademus on October 22, 2011, 01:21:38 am
Part of the point of vertices is that they have data, in this case colour. Thus gradients between points will be automatic. Therefore it would be better to be able to set the colour on a per-vertex bases. A per-shape colour would simply be a short-cut to setting all vertices' colour values to the same value. I doubt there can be a simpler or more flexible way than that.
Title: The new graphics API in SFML 2
Post by: Laurent on October 22, 2011, 07:34:56 am
Yeah, but I wanted to get rid of all these SetPointXxx functions. People usually don't know where the point at index N is located, since the geometry was built automatically. Thus it's hard to figure out which color to map to which point to get the desired result; a ColorGradient would be a simple (but limited) way to do that.

And since full flexibility can be achieved with sf::VertexArray anyway, high-level classes don't need to provide all the possible features.

Another solution is to subdivide geometry to allow more complex color gradients. But then Nexus is right, it's hard to get the color at a given position. And people that use a single color wouldn't be able to find it back easily with the getter.
Title: The new graphics API in SFML 2
Post by: Laurent on October 22, 2011, 02:39:21 pm
I think I'll start with the simplest API for sf::Shape: a single fill color/outline color, and for texturing I'll use a texture rect instead of allowing to change the texture coordinates of each point.
Title: The new graphics API in SFML 2
Post by: Mikademus on October 22, 2011, 08:01:01 pm
Well, if you're thinking of specialised classes for rects and other shapes, then adjust the API accordingly.

Rect:
enum Poiint { topLeft, topRight, bottomLeft, bottomRight }
setColour( Point point, Colour colour );
...

And similar enums and methods for the other shapes. For the generic Shape class I don't think you can get away from the setColour( index, colour ), and people that need that class should not really have any problems with understanding that interface.
Title: The new graphics API in SFML 2
Post by: Laurent on October 22, 2011, 08:45:46 pm
Quote
And similar enums and methods for the other shapes

And what would these enums be, for other shapes such as circle, star or triangle? ;)
Title: The new graphics API in SFML 2
Post by: Mikademus on October 22, 2011, 10:02:31 pm
Quote from: "Laurent"
Quote
And similar enums and methods for the other shapes

And what would these enums be, for other shapes such as circle, star or triangle? ;)


Well, for manual point setting I would imagine sticking with the vanilla setPoint/Colour/etc( index ) of Shape, but you could have methods like Star::setStarType() taking some preset star types (the enums { fivePoint, sevenPoint, etc }) but it is not elegant.

My point is that I don't think you'll be able to create an alternative to the setPointXxx() solution that retains flexibility. The Gradient class will not really be simpler but will be less useful and adjustable, and removing gradients isn't a good idea at all.
Title: The new graphics API in SFML 2
Post by: Laurent on October 22, 2011, 10:19:29 pm
Quote
removing gradients isn't a good idea at all

Do you really think people used them a lot?
Title: The new graphics API in SFML 2
Post by: Mikademus on October 22, 2011, 10:27:05 pm
Can only talk for myself, but I use individual colours for points pervasively in my project. In particular in my GUI system. I appreciate the desire to improve a library, and I would rank the benefits and motivations for doing so as follows

1) Increased stability
2) Improved and additional functionality (features and flexibility)
3) Increased usability (accessibility)
4) Increased efficiency
5) Improved elegance (code aesthetics)

In this case removing the facility would reduce functionality and kill existing code, will not really increase usability, and any elegance effect would be subjective.

[Edit]
Unless I misunderstood something and the ability to set individual point (vertex) colours, texture coordinates etc will be retained without losing functionality, but in another form.
Title: The new graphics API in SFML 2
Post by: Nexus on October 22, 2011, 10:28:18 pm
I think having only the possibility to set a texture by setting each point's texture coordinate is too user-unfriendly. So either use only one texture per shape, or write a function that automatically assigns tex coords. Would the setting of point-wise tex coords be much more work when one used sf::VertexArray instead of sf::ConvexShape?

About gradients, I don't know whether people have used them a lot. I once used them for a GUI button... But again, I prefer to keep a single color like in the old API. Point colors can then be added without API breaks, if necessary -- or be treated by sf::VertexArray.
Title: The new graphics API in SFML 2
Post by: Laurent on October 23, 2011, 10:08:32 am
Quote
I use individual colours for points pervasively in my project

Can you show me a typical use case of what you do?

Quote
In this case removing the facility would reduce functionality and kill existing code, will not really increase usability, and any elegance effect would be subjective.

Like I said, people don't know where points are located (point 0 could be the one on the left, on the right, in the middle, ...), so how could they assign colors to them? It can only work if they set the points positions themselves.

Quote
I think having only the possibility to set a texture by setting each point's texture coordinate is too user-unfriendly.

Yeah. That's why I want to have a "texture rect" property instead. Even for ConvexShape (it's a property of the Shape base class).

Quote
Would the setting of point-wise tex coords be much more work when one used sf::VertexArray instead of sf::ConvexShape?

No, I think it doesn't make any difference. The only difference between Shape and VertexArray is that Shape builds a list of triangles out of a convex shape, and computes the outline automatically. But once you have the points positions, the rest is straight-forward if you use a VertexArray, it's just a matter of assigning color and texcoords to the vertices -- it wouldn't be easier if it was implemented in sf::Shape.

Quote
But again, I prefer to keep a single color like in the old API. Point colors can then be added without API breaks, if necessary -- or be treated by sf::VertexArray

I don't want to mix several colors in one entity, people can't handle that. A "global" color and a "point" color is already too confusing for people. There are definitely too many threads about that on the forum :)
Title: The new graphics API in SFML 2
Post by: gsaurus on October 23, 2011, 12:31:02 pm
Keep it simple with the most common functionalities. Everything else fit in "advanced features" with VertexArray (I liked Vertex/Mesh :lol:, cleaner).

Use a single texture, don't forget to repeat it along the shape and provide transformations for the way the texture is applied (I think that scaling the texture is commonly used)

Eventually you can create a static function on ConvexShape to generate a VertexArray for those who want full access to a shape as a VertexArray, but doesn't know exactly how to build it efficiently.
Title: The new graphics API in SFML 2
Post by: Nexus on October 23, 2011, 01:03:17 pm
If you say the point-wise functionality isn't much more complicated to achieve with sf::VertexArray, then I agree to keep sf::Shape very simple, that is, one color and one texture per shape.

About the texture rect... Where is it located in a sf::Shape? Do you compute a bounding rect around all points, i.e. take min/max of X and Y point coordinates?
Title: The new graphics API in SFML 2
Post by: Laurent on October 23, 2011, 01:20:08 pm
Quote
Use a single texture, don't forget to repeat it along the shape

That's an interesting point. If I provide a "texture rect" property, people won't be able to repeat a texture on a shape, only take a sub-rectangle of it (unless  a rect bigger than the texture is used, but it's not very clean).

Quote
About the texture rect... Where is it located in a sf::Shape? Do you compute a bounding rect around all points, i.e. take min/max of X and Y point coordinates?

Absolutely. I map the texture rect on the bounding rect of the points, and interpolate the texture coordinates accordingly for each point.
Title: The new graphics API in SFML 2
Post by: gsaurus on October 23, 2011, 02:41:33 pm
Well, by default you may repeat the texture rect along the shape (or trunk if the texture rect is bigger than the shape) instead of distorting it to fit the shape bounds.
You may provide a SetTextureTransform(sf::Transform) to allow users to define the texture offset (position relative to the top-left bound of the shape), scale and rotation.
Stretching the texture to fit the shape bounds is a scale operation based on the shape bounds and the texture rect.

Or you can separate the texture mapping in a separated class, like TextureMapping, where you define those things separately (source texture, subrect and transformation). Then Shape have a getter and setter for the TextureMapping (that mapping class could be used for other things too, but I prefer not to think about it now..).

Or if you think it's too confusing, instead of all of that just provide a stretch property that can be activated to make the texture rect fit the shape bounds, and deactivated to have the texture at it's original size repeated or trunked by the bounds.

I think that the important is to think about what users will want to do more often with textures over shapes, and to keep in mind that some won't use textures at all anyway (that's why the TextureMapping possibility)
Title: The new graphics API in SFML 2
Post by: Laurent on October 23, 2011, 02:58:37 pm
Well, I want things to be simple. I don't want to start thinking about complicated texturing stuff.

A stretch property wouldn't be enough, you need to be able to define a sub-rect (position and size) inside the texture.
Title: The new graphics API in SFML 2
Post by: gsaurus on October 23, 2011, 06:30:27 pm
Yes, off course. Where I said texture, I meant sub-rect of the texture.

Possible example with TextureMapping class:
Code: [Select]
sf::Shape myShape;

sf::TextureMapping texMap;
texMap.SetTexture(someTexture);
texMap.SetTextureSubrect(someRect);
texMap.Scale(2.f, 2.f);
// the subrect of the texture will be repeated along the shape, with a scale of 2x
myShape.SetTextureMapping(texMap);

The example is illustrative only, need refinement.

It also makes easier to use the same mapping for several shapes.
Title: The new graphics API in SFML 2
Post by: Groogy on November 02, 2011, 02:53:31 am
If you still want suggestions, how about rendering to multiple buffers using one single draw call? For practical uses of this you look at post processing effects which depend on data available during scene render. Games use this to create true motion blur effect.

I'm just comming with ideas and don't expect you to implement them. Just putting it out there for consideration so to speak. And this suggestion is extra tricky and a bit advanced. But I guess a function to maybe attach a render target onto another. Though. I'm writing this just before going to bed. So I might have a proper design pattern that is fitting tomorrow if you are interested.

I can come with more suggestions like this if you want. Or I can shut up if you feel that I'm making your task so much more irritating. :D  :roll:

Note: if it helps I can give full implementation details on how it would be used.
Title: The new graphics API in SFML 2
Post by: Laurent on November 02, 2011, 08:06:26 am
Ideas are always welcome ;)

However the goal here is to find a better API for tasks that SFML already does (= drawing 2D entities easily and efficiently), not to implement fancy new techniques that run only on the most recent GPUs.

Let's focus on the basics for SFML 2.0, and keep this kind of new features for future versions of SFML 2.x ;)
Title: The new graphics API in SFML 2
Post by: Groogy on November 02, 2011, 02:55:36 pm
Quote from: "Laurent"
Ideas are always welcome ;)

Great! At work right now but I can come with some later.

Quote from: "Laurent"
However the goal here is to find a better API for tasks that SFML already does (= drawing 2D entities easily and efficiently), not to implement fancy new techniques that run only on the most recent GPUs.

No problem, what I had in mind with this was actually for 2D. Most effects known in 3D games can be applied in 2D games as well. You would be amazed of how many of these effects are actually done in post-projection space. And I think rendering to multiple targets have been available for quite a long time and most graphics card support it.

True motion blur basics works on that while we are rendering the scene we also compute a velocity value for each vertex by remembering the previous frame transformation and just calculate the difference vector between the positions. To be able to do this you have two buffers you write to, one being the actual fragment color and the second being the velocity buffer(just a texture we interpret in the shader as we want). Then the velocity buffer is bound as a texture to the post processing shader that actually does the true motion blurring depending on the velocity for that pixel. Nothing fancy, nothing advanced. Just a little math and the fact that you render to two targets at the same time. Of course you can do the velocity calculation in it's own draw call as well if you still feel that multiple buffers shouldn't be implemented yet. So it's not a deal breaker ^^
And since we are doing 2D graphics, we got pretty much unlimited juice to squeeze out :)

Quote from: "Laurent"
Let's focus on the basics for SFML 2.0, and keep this kind of new features for future versions of SFML 2.x ;)

Sure, and I think I have written down something somewhere that is just about that. Don't remember if it was the home or work computer. I'll get back to you :)
Title: The new graphics API in SFML 2
Post by: Tex Killer on November 02, 2011, 07:51:22 pm
Hello.
I'm sorry for not reading all the messages on the topic, but I have an idea I want to discuss.
Are you planning on revewing the audio API?
As I have checked, you can't play one piece of song right after another piece... you cant mix sounds in the current API. Am I correct?
I have made a little improvement on my local version of SFML code to allow such things. Don't you think it deserves be on the public one too?
Thank you all for your work and dedication.
Title: The new graphics API in SFML 2
Post by: Laurent on November 02, 2011, 09:04:25 pm
Quote
Are you planning on revewing the audio API?

Nop. sfml-audio won't be touched in SFML 2.0, but it will probably be improved later in SFML 2.x. However for big changes that break everything, you'll have to wait for SFML 3 ;)

Quote
As I have checked, you can't play one piece of song right after another piece

True.

Quote
you cant mix sounds in the current API

If you mean "play several sounds at the same time", then you definitely can do this.

Quote
I have made a little improvement on my local version of SFML code to allow such things. Don't you think it deserves be on the public one too?

I'd be glad to see this. Don't hesitate to create your own repository on github by forking SFML, and send me pull requests, so that I (and everybody) can see what improvements you have there :)
Title: The new graphics API in SFML 2
Post by: Tex Killer on November 02, 2011, 09:17:15 pm
Well, I'd have to polish my code before showing, mainly because most part of the terms are in portuguese. Basically, in my version you set up a list, and add to that list the files you want played - specifying the start and end millisecs each time you add a file to the list - and then play the list. Once one entry is finished the other starts right away, in the same thread. I've made it buffered, extending the Music class and coding some more things.
I'll show what I did soon, then. Thanks.
Title: The new graphics API in SFML 2
Post by: Laurent on November 02, 2011, 09:18:27 pm
Quote
I'll show what I did soon, then. Thanks.

Ok great :)

But please open a new thread when you do so -- this one is about the graphics API :P
Title: The new graphics API in SFML 2
Post by: Groogy on November 02, 2011, 10:12:12 pm
And as a nice segway into the graphics api. Will shaders be able to set matrix variables to transform objects? I don't see why you shouldn't be able to.
Title: The new graphics API in SFML 2
Post by: Laurent on November 02, 2011, 10:18:41 pm
Quote
And as a nice segway into the graphics api. Will shaders be able to set matrix variables to transform objects? I don't see why you shouldn't be able to

Good idea, indeed.
Title: The new graphics API in SFML 2
Post by: Groogy on November 08, 2011, 10:18:29 am
Another idea just putting it out there for your consideration.

how about instancing to lower the amount of draw calls to the GPU? Don't know exactly how it's done in OpenGL and that would need a little research but the interface in SFML would be something like this:

Code: [Select]
window.Draw( meshAndAnyOtherValues, arrayOfTransformations );

If you have no clue on how this would work under the hood I can probably do some research for how to actually implement it in OpenGL and also give you the underlying basics behind it.

And yeah it's just a silly optimization but it gave me a huge performance increase with DirectX, something like 30-50 FPS with batching to 500 FPS with instancing.

Update: Little quick look, it's supported trough OpenGL as an extension and it is supported by graphics card since year 2004. So it's pretty old. The OpenGL context you default to was also for instance released that year.

http://www.opengl.org/registry/specs/EXT/draw_instanced.txt
Title: The new graphics API in SFML 2
Post by: Laurent on November 08, 2011, 12:46:47 pm
I think that I'll definitely switch to an OpenGL 2 architecture (with shaders and everything) after SFML 2.0 is released, and I'll seriously consider all these techniques that require GL 2 extensions.

But for the new API that we are discussing here, like I already said, I'm not interested in adding new features, I just want to do the same things as before, but with an API which allows more flexibility.

Quote
Little quick look, it's supported trough OpenGL as an extension and it is supported by graphics card since year 2004

The spec says "GeForce 8 series (November 2006)". It seems like a very recent (and unsupported) feature to me.

Quote
The OpenGL context you default to was also for instance released that year.

Hum? The default context version is the lowest one that the card can provide, SFML has no limitation on it.
Title: The new graphics API in SFML 2
Post by: Groogy on November 08, 2011, 01:48:52 pm
Quote from: "Laurent"
I think that I'll definitely switch to an OpenGL 2 architecture (with shaders and everything) after SFML 2.0 is released, and I'll seriously consider all these techniques that require GL 2 extensions.

Awesome!

Quote from: "Laurent"
But for the new API that we are discussing here, like I already said, I'm not interested in adding new features, I just want to do the same things as before, but with an API which allows more flexibility.


Noted!

Quote from: "Laurent"
The spec says "GeForce 8 series (November 2006)". It seems like a very recent (and unsupported) feature to me.
Hmm my bad, the wikipedia page said something else but I guess that's incorrect information. The extension is included with OpenGL 3.0 as official extension as well but only depends on 2.0 but I wouldn't say unsupported. It's common and a must for repetitive graphics. Or else you'll walk around in a world with 5 FPS or something no matter how much of a monster of computer you have.

DirectX9 and 10 for instance include it hardwired into the whole thing.

http://en.wikipedia.org/wiki/Geometry_instancing

I would also like to say that since instancing gives this great performance boost by reducing draw calls it should be implemented in the future and maybe provide a just like you did for Shaders, a "IsAvailable" function.

I am actually getting some pretty cool creative ideas that could be done with SFML thanks to instancing. First being simple voxel graphics in 2D(Might sound stupid but don't know what else to call it) :) But like said, something for the future.

Quote from: "Laurent"
Hum? The default context version is the lowest one that the card can provide, SFML has no limitation on it.
If the user provides nothing else you attempt to create a 2.0 context.

http://www.sfml-dev.org/documentation/2.0/structsf_1_1ContextSettings.php#aafe35f8e257f9d1e496ed64e33e2ee9f

Update: AH! The GeForce 8 is a revised version I think if you look at the bottom:
Quote
Revision History

      Rev.    Date    Author    Changes
      ----  --------  --------  -----------------------------------------
      1.5   05/09/08  gold      Removed extraneous parameters to DrawArrays
                                and DrawElements in chapter 2 pseudocode


Which is probably nothing you'll have to worry about using GLEW.
Title: The new graphics API in SFML 2
Post by: Laurent on November 08, 2011, 02:53:05 pm
Quote
I wouldn't say unsupported. It's common and a must for repetitive graphics. Or else you'll walk around in a world with 5 FPS or something no matter how much of a monster of computer you have.

For big commercial games it's definitely old enough to be used. But for SFML it's too recent (don't forget that I do simple 2D and that it should work on every platform), it's already lightyears away from my requirements.

Quote
If the user provides nothing else you attempt to create a 2.0 context.

No, I create a context (with no requirement) and the driver may choose to give me a 1.2 context. It will work.

The thing that most people don't know is that you can manage context versions only above 3.0. Below (1.x and 2.x) there's no choice, you get what the driver gives you. So the default "2.0" in sf::ContextSettings is purely arbitrary. In fact you can pass any number below 3.0, the result will be the same. You can get 1.2 as well as 4.1, it's up to the driver.
Title: The new graphics API in SFML 2
Post by: Laurent on November 08, 2011, 02:54:29 pm
Quote
AH! The GeForce 8 is a revised version I think if you look at the bottom

I'm not sure.
It still says:
Quote
Status

    Shipping for GeForce 8 Series (November 2006)
Title: The new graphics API in SFML 2
Post by: Groogy on November 08, 2011, 03:30:15 pm
Hmm true... Which is weird because most of the Instancing is done in the driver and not directly on the GPU. And besides it has been supported by DirectX9 which works with any card that supports OpenGL 2.0 so it's quite confusing.

Anyway I think that all 2.0 compliant drivers will support the extension since that is the dependency and we can only trust that. Because according to OpenGL it has officially supported Instancing since 3.0 (but the extension was created in 2.0).

And actually looking more into it. The first GPU to support 3.0 was Nivida 8 Series so no wonder that's what it says if the extension is integrated in 3.0, I.E it is shipped together with the driver.  Of course I'm no expert on how the extensions in OpenGL works and I am not entirely sure of what GLEW actually does. But from my point of view it looks like the extension would just load nicely. I could attempt and create some example and try it out on different 2.0 machines.

The only loose end that I see is the EXT_gpu_shader4 extension which is also a dependency and which adds more features to the shader language(But it's only dependency is 2.0 but it says something about supporting capabilities of newer hardware).

(Taken from OpenGL's coding resource)
http://www.opengl.org/sdk/docs/man3/xhtml/glDrawArraysInstanced.xml

any which way it's not a big loss. You can fake instancing on the CPU and still get big GPU/CPU performance boost but it costs quite a big amount of memory. (For those that might need it in the future) :)
Title: The new graphics API in SFML 2
Post by: Mikademus on November 08, 2011, 03:42:20 pm
Since Font and Text was separated, this might also be the time to introduce a much needed extension to text styles. Especially outline colours but also shadows would be extremely appreciated additions.
Title: The new graphics API in SFML 2
Post by: Laurent on November 08, 2011, 03:55:47 pm
Quote
Anyway I think that all 2.0 compliant drivers will support the extension since that is the dependency and we can only trust that. Because according to OpenGL it has officially supported Instancing since 3.0 (but the extension was created in 2.0).

A dependency on 2.0 doesn't mean that anything which supports 2.0 will have this extension too. The only way to see how an extension is supported is to use this kind of software (http://www.realtech-vr.com/glview/).

Quote
You can fake instancing on the CPU and still get big GPU/CPU performance boost

How would you do that?

Quote
Since Font and Text was separated, this might also be the time to introduce a much needed extension to text styles. Especially outline colours but also shadows would be extremely appreciated additions.

I can't implement that easily.
Title: The new graphics API in SFML 2
Post by: Groogy on November 08, 2011, 04:29:17 pm
Quote
How would you do that?


It's not pretty, but it's how they originally did it before hardware support came. But I have to kind of go trough the basics of how instancing works in order to explain how I think. IF you are interested I could send it in a private message instead of bloating it here?

Any how this will not be implemented for SFML2 then. And faking it on the CPU can be done without SFML doing anything special behind the scene.
Title: The new graphics API in SFML 2
Post by: Laurent on November 08, 2011, 04:33:25 pm
Quote
IF you are interested I could send it in a private message instead of bloating it here?

Yes please :)
Title: The new graphics API in SFML 2
Post by: Mikademus on November 08, 2011, 04:45:01 pm
Quote from: "Laurent"

Quote
Since Font and Text was separated, this might also be the time to introduce a much needed extension to text styles. Especially outline colours but also shadows would be extremely appreciated additions.

I can't implement that easily.

What would be required, or are there particular problems associated with font rendering?
Title: The new graphics API in SFML 2
Post by: Laurent on November 08, 2011, 04:56:15 pm
Quote
What would be required, or are there particular problems associated with font rendering?

Fonts glyphs are pre-rendered, that's why effects are hard to achieve. Glyphs already come in two versions: bold and regular, which doubles the amount of video memory that sf::Font requires; I can't add more overhead.

In the future I might be able to add new effects, when text rendering will be rewritten to use shaders and distance fields.
Title: The new graphics API in SFML 2
Post by: Mikademus on November 08, 2011, 05:09:37 pm
Aah, ok, that explains it. Thanks for the explanation.

A thought: since creating a large set of textures with all combinations of styles is obviously unrealistic, an alternative possibility might be to request the creation of a font texture with a given (user-specified) combination of styles when a typeface is loaded. A specialised typeface like that would of course not be able to take any other styles, but it would solve principally all problems and satisfy all usage scenarios I can think of, as well as actually reduce memory footprint when only a particular style is needed.

The drawback of this solution is of course that colours would need to be part of the requested style.
Title: The new graphics API in SFML 2
Post by: Groogy on November 08, 2011, 07:15:54 pm
Alright I sent you a very LOOOOOONG message about instancing now :)
I tried to cut as many corners as possible and forced myself not to give you complete code examples to demonstrate what I mean, else I might had broken some buffer in PHP by the shear amount of text :twisted:
If anyone else want's it then just let me know and I'll PM it to you as well.
Title: The new graphics API in SFML 2
Post by: Ricky on November 09, 2011, 12:14:32 am
Quote from: "Groogy"
Alright I sent you a very LOOOOOONG message about instancing now :)
I tried to cut as many corners as possible and forced myself not to give you complete code examples to demonstrate what I mean, else I might had broken some buffer in PHP by the shear amount of text :twisted:
If anyone else want's it then just let me know and I'll PM it to you as well.


me  :o
Title: The new graphics API in SFML 2
Post by: Groogy on November 09, 2011, 01:41:13 am
Done ;)
Title: The new graphics API in SFML 2
Post by: Laurent on November 09, 2011, 07:36:16 am
Quote
A thought: since creating a large set of textures with all combinations of styles is obviously unrealistic, an alternative possibility might be to request the creation of a font texture with a given (user-specified) combination of styles when a typeface is loaded. A specialised typeface like that would of course not be able to take any other styles, but it would solve principally all problems and satisfy all usage scenarios I can think of, as well as actually reduce memory footprint when only a particular style is needed.

That's a possible solution. But like I said, text rendering will probably be rewritten soon and allow much more flexibility, so it's not worth changing it now :)

Quote
Alright I sent you a very LOOOOOONG message about instancing now

Thanks :D
Title: The new graphics API in SFML 2
Post by: Tank on November 09, 2011, 11:22:53 am
Quote from: "Laurent"
But like I said, text rendering will probably be rewritten soon and allow much more flexibility, so it's not worth changing it now :)

Will it get faster, too? sf::Text is the main framerate dropper in SFGUI applications. ;)
Title: The new graphics API in SFML 2
Post by: Laurent on November 09, 2011, 01:13:17 pm
Quote
Will it get faster, too? sf::Text is the main framerate dropper in SFGUI applications.

It should already be much faster with the new graphics API of SFML 2.0 -- as long as the text doesn't change every frame.

Distance fields, if I implement them in the future, should not improve performances that much. The main benefit of this technique is that you need only a single texture to store the glyphs for every possible size -- compared to one texture per size now.
Title: The new graphics API in SFML 2
Post by: Tank on November 09, 2011, 03:18:21 pm
Is that comparible to texture atlases?

Any chance that you push your current progress to the SFML experimental repository? I wouldn't mind if it doesn't build at all.
Title: The new graphics API in SFML 2
Post by: Tank on November 09, 2011, 03:22:49 pm
...if you mean SFML2's current state, here's what a simple benchmark shows:

(http://www.abload.de/thumb/with_textsrjuzy.png) (http://www.abload.de/image.php?img=with_textsrjuzy.png) (http://www.abload.de/thumb/without_textsblu75.png) (http://www.abload.de/image.php?img=without_textsblu75.png)

We did play around with caching texts into render textures, which (of course) boosted everything up at the cost of video memory. So are there optimizations for the new 2.0 API or are they already included?
Title: The new graphics API in SFML 2
Post by: Laurent on November 09, 2011, 03:44:46 pm
Quote
Is that comparible to texture atlases?

What do you mean?

Quote
Any chance that you push your current progress to the SFML experimental repository? I wouldn't mind if it doesn't build at all.

It's still too early to push something, sorry. But you can get all the relevant information about the new API in the dedicated thread.

Quote
...if you mean SFML2's current state

I mean SFML 2's next state :D
So the optimizations that I'm talking about are coming in the new API.

Quote
here's what a simple benchmark shows

These FPS are too high, the results are not really relevant. Add more stuff so that you reach ~100 FPS.
Title: The new graphics API in SFML 2
Post by: Tank on November 09, 2011, 04:40:33 pm
Quote from: "Laurent"
Quote
Is that comparible to texture atlases?

What do you mean?

http://en.wikipedia.org/wiki/Texture_atlas

Quote
It's still too early to push something, sorry. But you can get all the relevant information about the new API in the dedicated thread.

That's 13 pages which could probably compressed to one little list. ;)

Quote
I mean SFML 2's next state :D
So the optimizations that I'm talking about are coming in the new API.

Alright, this is clear now.

Quote
Quote
here's what a simple benchmark shows

These FPS are too high, the results are not really relevant. Add more stuff so that you reach ~100 FPS.

I had to instantiate 800 buttons to make the FPS drop to 100 FPS, however the "good performance" might happen due to using sf::View clipping to the window's area (haven't checked if SFML does culling in sf::View).

(http://www.abload.de/thumb/with_textsneuna.png) (http://www.abload.de/image.php?img=with_textsneuna.png) (http://www.abload.de/thumb/without_textskuu64.png) (http://www.abload.de/image.php?img=without_textskuu64.png)
Title: The new graphics API in SFML 2
Post by: Laurent on November 09, 2011, 04:52:34 pm
Quote
http://en.wikipedia.org/wiki/Texture_atlas

I know what a texture atlas is, but I don't understand your question. Well, now that I read it again, I understand that "comparible" meant "comparable" and not "compatible" :lol: so it makes sense now.

Distance fields are not comparable to texture atlases, it's just that a single "instance" of the glyph will enable to render it for any size, instead of having one instance for every character size.

Quote
That's 13 pages which could probably compressed to one little list.

Yeah, I'll try to post an update as soon as things get a little cleaner (and clearer) on my side.

Quote
however the "good performance" might happen due to using sf::View clipping to the window's area (haven't checked if SFML does culling in sf::View).

It doesn't.
Title: The new graphics API in SFML 2
Post by: Tank on November 09, 2011, 05:00:53 pm
Thanks for clarification and sorry for the typo. ;)