Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Draw pixels in real-time  (Read 2129 times)

0 Members and 1 Guest are viewing this topic.

Umbre

  • Newbie
  • *
  • Posts: 16
    • View Profile
Draw pixels in real-time
« on: March 15, 2024, 02:33:46 pm »
Hello,
I'm looking to draw pixels in real-time with SFML, and I'm hesitating between sf::Image and sf::RenderTexture. What happens internally with these classes? What's the best practice between this,
sf::Image image;
image.create(1920, 1080);

image.setPixel(100, 200, sf::Color::Red);

sf::Texture texture;
texture.loadFromImage(image);
sf::Sprite sprite(texture);
window.clear();
window.draw(sprite);
window.display();
 
and that ?
sf::RenderTexture renderTexture;
renderTexture.create(1920, 1080);

renderTexture.clear();
sf::Vertex vertices[] = {sf::Vertex(sf::Vector2f(100, 200), sf::Color::Red)};
renderTexture.draw(vertices, 1, sf::Points);
renderTexture.display();

sf::Sprite sprite(renderTexture.getTexture());
window.clear();
window.draw(sprite);
window.display();
 


Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Draw pixels in real-time
« Reply #1 on: March 17, 2024, 06:14:51 pm »
An sf::Image is basically just an array of pixels in standard RAM.
Updating (or loading) the texture from an image copies this memory (either fully or in part) to the graphics card memory (the 'image' of a texture is stored on graphics card memory). This is then used by the graphics card to when drawing the sprite (in this case). Updating the texture from the image is the heaviest part of this operation but - depending on how much you may be processing pixels - CPU image processing may also be heavy.

An sf::RenderTexture is similar to an sf::Texture in that it already resides in graphics card memory and can be used by the graphics card for both drawing to (when changing it) and drawing from (when drawing the sprite in this case).
So, in theory, this is lightest process since you don't need to transfer anything (much) from CPU to GPU to be able to draw the render texture. However, anything you do change does need to be sent to the graphics card so if that is every pixel every time, this could be even heavier as each vertex also has extra information (i.e. a position and a texture co-ordinate) that wouldn't change.
If you are only changing (modifying pixel colours) 'some' pixels or are 'moving' (changing their positions rather than them having static pixel positions) them, this could be more efficient.
Also, this method also allows you to let the graphics card do some processing. e.g. you can use vertex or geometry shaders to modify the 'pixels' (vertices) by just giving parameters.

Note that you do something similar using fragment shaders and an image/texture.



In conclusion:

If you are modifying every pixel every time (whether it needs modifying or not), using an sf::Image is likely the simplest and possibly fastest method. Use this for video input, for example.

If you are only modifying a few pixels and/or not modifying them often, a vertex array with a render texture could be more efficient.

Note that an sf::VertexBuffer can also add additional features for this but may not be more efficient if transferring a lot of information.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Umbre

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Draw pixels in real-time
« Reply #2 on: March 31, 2024, 07:18:20 am »
Sorry for the late reply. Thank you very much.
If I understand correctly, when I call renderTexture.getTexture(), the texture does not go back through the RAM; it stays on the graphics card, even if I use it to draw something else afterwards. Is that correct? And using an sf::RenderTexture would be the method that most closely resembles SDL, where everything is thought of in terms of pixel arrays, wouldn't it?
Another question. When using an sf::RenderTexture, what should the coordinates of the drawn vertices be for them to correspond properly to the points of the texture? If I'm not mistaken, an sf::Point vertex at (0.,0.) doesn't draw anything. Should the points be offset by 0.5 to hit the correct pixels?
I also did some tests with fragment shaders. Is the GLSL loaded by SFML portable across other platforms? For example, I code on macOS and I believe SFML uses OpenGL 2.1 in this environment. Will my shaders work on other platforms with more modern versions of OpenGL?
Thanks again for your help.
Have a good day.
« Last Edit: March 31, 2024, 07:28:07 am by Umbre »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Draw pixels in real-time
« Reply #3 on: April 01, 2024, 11:51:35 pm »
You are very welcome. Glad what I said helped.

Yes, indeed. Textures (from a render texture or not) are on (and stay on) the graphics card. "Getting" a texture really just gives you access to the object that controls it (sf::Texture). sf::Textures that you create yourself can be modified by updating it (copies image from RAM to graphics card) but the sf::Texture you get from a render texture is const and cannot be modified so everything stays on the graphics card.

All (pixel) render targets work the same way so it's the same drawing to a window as drawing to a render texture. That is, yes, co-ordinates would likely require offsetting by (0.5, 0.5). Note that just as windows, you can change a render texture's view so draw co-ordinates might not match the pixels exactly. If you need perfect matching, you should make sure the view is as required. In fact, you could move the (default) view by -(0.5, 0.5) and then draw to integer values!

Modern versions of OpenGL are generally compatible with older versions, yes. The version you choose to use with SFML (or in your shaders) will determine their compatibility.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Umbre

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Draw pixels in real-time
« Reply #4 on: April 03, 2024, 04:17:38 pm »
Thank you very much for your help, everything is very clear. I will come back if needed.
Have a good day.