SFML community forums

Help => Graphics => Topic started by: NateS on February 17, 2013, 03:04:48 am

Title: drawing quad efficiently for Spine
Post by: NateS on February 17, 2013, 03:04:48 am
I'm working on SFML support for Spine (http://en.sfml-dev.org/forums/index.php?topic=10624.0). I need to draw a number of textured quads (not rects!). What is the most efficient way to do this? Can I batch the drawing? Likely the textures come from a texture atlas. I am using SFML 2.0. I know little about SFML so I thought I'd ask what was most efficient since others will be using the Spine runtime I'm writing.
Title: Re: drawing quad efficiently for Spine
Post by: Weeve on February 17, 2013, 04:13:11 am
by Quad, I immediately think of OpenGL, and could easily help you if your talking a 3D layout of 2D, but that would render stretch (I believe Spine is 2d?) if you don't want stretch, then why use a quad (all images are rectangles, anyway)? explain exactly what you want please?
Title: Re: drawing quad efficiently for Spine
Post by: Ancurio on February 17, 2013, 04:35:20 am
Hm, the way I would do it personally is to create an sf::VertexArray (http://www.sfml-dev.org/documentation/2.0/classsf_1_1VertexArray.php) with the number of quads*4 you'll be using (which won't have to be resized since you'll be using the same amount of quads throughout the animation, right?), attach them to the correct texture positions and then update their screen positions as the animation proceeds. This way you can always draw them in one call.
Title: Re: drawing quad efficiently for Spine
Post by: Weeve on February 17, 2013, 04:37:53 am
Ahh.. so thats what he meant by quad.. btw this is addicting: http://en.sfml-dev.org/forums/index.php?action=who
Title: Re: drawing quad efficiently for Spine
Post by: Halsys on February 17, 2013, 04:56:14 am
Quote
I need to draw a number of textured quads
Well because your making a library to SFML, Make a class using sf::RectangleShape's(You wanted Quads,Closest thing) or sf::Sprite.
In this class have a array(Fast) or std::map(Convenient) of these sf::RectangleShapes's or sf::Sprites.
Then program a series of function that will change/load or check variables for the user...Kinda like SFML's.
As for drawing them to the screen, I would imagine making a inheritance to sf::Drawable would be the first step but I dont know how/where Laurent draws this stuff on the screen. Or if your lazy you can do it like me and make a function like this:
Spine::Draw(sf::Window* Window)
{
for(int I = 0;I == NumOfDrawables;I++)
{
Window->Draw(*Insert Drawable*);
}
}
 
Of course somewhere in there you might want to make a way to update positions/rotations for the animation.But of course this is all what I would do. But if you want more help, talk to Laurent(Author) or eXpl0it3r(Very Helpful)... They no more than I do apparently.
Title: Re: drawing quad efficiently for Spine
Post by: krzat on February 17, 2013, 06:42:59 am
The most standard way is to use sprite classes. You can also try my xna-style spritebatch: http://pastebin.com/Wueaknvz . It should be more efficient.
Title: AW: drawing quad efficiently for Spine
Post by: eXpl0it3r on February 17, 2013, 08:15:59 am
As Ancurio already pointed out the most efficient way and most closest to OpenGL, is using sf::VertexArray or better std::vector<sf::Vertex>.
That way you can have one spritesheet texture and draw your whole character in one draw call.

The complicated part of this approach is that you'll have to transform the vertices manually on your own.
Title: Re: drawing quad efficiently for Spine
Post by: Laurent on February 17, 2013, 09:20:19 am
Vertex arrays are indeed the fastest possible way to draw batches of geometry, even dynamic ones. But you have to calculate the vertices positions manually, you can't use the GPU's transformations capabilities. However, using one transform matrix for each quad would be inefficient, so I think that a vertex array is really the best solution for you, especially since you'll use a single texture for all your nodes, and their count is constant.

For the transformations, unless you already have you own class, you can use sf::Transform which is a simple encapsulation of a 3x3 matrix.

To make the higher-level class (the one that users will manipulate and draw) SFML-friendly, you can make it inherit from sf::Drawable (allows it to be drawn with a call to window.draw(entity)), and from sf::Transformable (defines transformation functions to change the position, rotation and scale of the entity).
Title: Re: drawing quad efficiently for Spine
Post by: NateS on February 17, 2013, 12:23:57 pm
Great info, thanks for the jump start. Will see how far I can get today. I'm already calculating the vertices, so that is no problem. All I need to do is draw the little bastards! :)
Title: Re: drawing quad efficiently for Spine
Post by: Ancurio on February 17, 2013, 03:56:19 pm
Great info, thanks for the jump start. Will see how far I can get today. I'm already calculating the vertices, so that is no problem. All I need to do is draw the little bastards! :)

sf::VertexArray is already a Drawable, so it goes straight into the window.draw() call ^^ Just remember to bind the texture, or pass it as part of a RenderStates instance.
Title: Re: drawing quad efficiently for Spine
Post by: masskiller on February 19, 2013, 12:41:29 am
I coded this class a while ago: https://github.com/SFML/SFML/wiki/Source%3A-High-Performance-Sprite-Container (https://github.com/SFML/SFML/wiki/Source%3A-High-Performance-Sprite-Container)

It's still lacking some features and good naming, but it has almost all the basic transformations programmed to work through a std::vector of sf::Vertex.
Title: Re: drawing quad efficiently for Spine
Post by: Laurent on February 19, 2013, 08:00:01 am
Quote
I coded this class a while ago: https://github.com/SFML/SFML/wiki/Source%3A-High-Performance-Sprite-Container

It's still lacking some features and good naming, but it has almost all the basic transformations programmed to work through a std::vector of sf::Vertex.
I would recommend this kind of class for the final usage, not as a middleware to implement high-level entities. It just adds unnecessary layers, and removes some flexibility. As long as you need an efficient storage for implementation details, I'd recommend going with vertex arrays directly; especially for people who are not complete beginners.