Glusoft

Textures, Sprites and Shapes with SFML

In this tutorial we will dive deep into the differences between textures, sprites and shapes with SFML.

Textures SFML : sf::Texture

What is sf::Texture?

sf::Texture is a class in the SFML library that represents an image stored in the graphics card’s memory (VRAM), optimized for fast rendering. It’s essentially a container that holds pixel data (like a .png, .jpg, etc.) and is used to draw graphics efficiently.

Why do we need sf::Texture?

When working with graphics in games or multimedia apps, drawing images (sprites) repeatedly to the screen from RAM would be too slow. Instead, sf::Texture uploads the image to the graphics card once, and then the GPU can render it very quickly every frame.

The texture is basically an image loaded into the VRAM, the VRAM is the memory of the graphics card if you have a graphic card with dedicated memory. If you have an integrated memory card the RAM of the computer is used instead.
That is good to know but what does it means concretly for a texture ?

Textures are used for the sprites if you want to display it on the screen.

If you want to access the pixels and do some images manipulation other than size and rotation you need to have the image in the RAM.
For that that you will use the class sf::Image, keep in mind if you want to display the image after some pixels modifications you will need to convert bakc the image to a texture.

The operation of loading textures / images, converting between textures and images are slow operations.

So if you really need to do it, do the work once and cache it!
If you want to know all the methods available for the sf:Texture go check the sf:Texture Documentation
For the sf::Image : sf::Image Documentation

Sprites SFML : sf::Sprite

What is sf::Sprite?

sf::Sprite is a class in SFML that represents a drawable object that can display a texture (an image) on the screen. Think of it as a 2D image container that lets you easily move, scale, rotate, and render an image using a sf::Texture.

Why use sf::Sprite?

While a sf::Texture holds the image data, it cannot be drawn on its own. sf::Sprite is the thing you actually render. It references a sf::Texture and handles all the transformations (position, rotation, scaling) you’d expect in a game or multimedia app.

If you want to display textures you must use sprites. Why ? Well to display something you need to have a sf::RenderWindow or a sf::sf::RenderTexture. In the documentation the draw methods are:

void 	draw (const Drawable &drawable, const RenderStates &states=RenderStates::Default)
void	draw (const Vertex *vertices, std::size_t vertexCount, PrimitiveType type, const RenderStates &states=RenderStates::Default)
void 	draw (const VertexBuffer &vertexBuffer, const RenderStates &states=RenderStates::Default)
void 	draw (const VertexBuffer &vertexBuffer, std::size_t firstVertex, std::size_t vertexCount, const RenderStates &states=RenderStates::Default)
classes Hierarchy - shapes, textures, sprites

Shapes SFML

Circles : sf::CircleShape

To draw a circle you must use the class sf::CircleShape, in the constructor you must specify the radius of the circle. Then you can set the filling color and the outline color.

sf::CircleShape shape(30.f); // shape of a circle
shape.setFillColor(sf::Color(0, 0, 255));
shape.setOutlineThickness(5.f);
shape.setOutlineColor(sf::Color(255, 0, 0));

You can also set a texture with shape.setTexture(&tex); and only take a small part of the texture with shape.setTextureRect(sf::IntRect(2, 5, 50, 20));

Rectangle : sf::RectangleShape

To draw a rectangle you will need to use the class sf::rectangleShape:

sf::RectangleShape rectangle(sf::Vector2f(10.f, 30.f)); // shape of a rectangle
rectangle.setSize(sf::Vector2f(200.f, 50.f));

Polygon : sf::ConvexShape

To display a polygon you can use the class sf::ConvexShape:

sf::ConvexShape poly;

poly.setPointCount(6);
poly.setPoint(0, sf::Vector2f(142.f, 112.f));
poly.setPoint(1, sf::Vector2f(204.f, 74.f));
poly.setPoint(2, sf::Vector2f(234.f, 101.f));
poly.setPoint(3, sf::Vector2f(261.f, 145.f));
poly.setPoint(4, sf::Vector2f(176.f, 184.f));
poly.setPoint(4, sf::Vector2f(135.f, 143.f));
poly.setFillColor(sf::Color(255, 0, 0));

The points need to be in clockwise order or anti-clowise order !
If you have concave shapes you can split it into a convex shapes into triangles with a Delaunay triangulation, you can find libraries and algorithm to compute the decompositon.

Now you now the difference between textures, sprites and shapes with SFML.