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

Author Topic: texture.update(pixels): is it normal to be so slow? [Full working code inside]  (Read 582 times)

0 Members and 1 Guest are viewing this topic.

LakySimi1

  • Newbie
  • *
  • Posts: 25
    • View Profile
Hi everyone,
the code provided goes at 540fps on 960x540 with an i5-10400; is not slow in an absolute way but considering what i am doing.. it is, and, most triggering to me is that therefore it is too unoptimized.
Drawing a genering monochrome rectangle with same dimensions goes up to 2500ish fps.

I compromise on go slower because i'm using CPU rather than GPU but it seems a bit too bad to me.

I want to draw the game screen pixel per pixel, i find it funny to come up with al graphic tweaks and have the power to intervent arbitrarily on any pixel i want: there is a way to do what i do in my code but more correctly/optimixed? There are other ways to do what i want to do?

Thak you very much in advance!
Quote

#include <SFML/Graphics.hpp>

using namespace std;

const int H = 1080/2; //Window height
const int W = 1920/2; //Window width

sf::Uint8* pixels = new sf::Uint8[W * 800 * 4]; //Array for the pixels (R,G,B,Alpha)


//Fill pixel array with values (all 100 for simplicity's sake)
void CreateImage(int nCol, int row_0, int row_1)
{
    for (int ir = row_0; ir < row_1; ir++)
    {
        for (int ic = 0; ic < W; ic++)
        {
            pixels[(ir * W + ic) * 4] = 100;        //red
            pixels[(ir * W + ic) * 4 + 1] = 100;    //green
            pixels[(ir * W + ic) * 4 + 2] = 100;    //blue
        }
    }
}



int main()
{
    sf::RenderWindow window(sf::VideoMode(W, H), "SFML works!"); //Create window
    window.setFramerateLimit(0); //No limit to framerate

    //Stuff used to generate final screen image (found online)
    sf::Texture texture;    texture.create(W, H);   sf::Sprite sprite(texture);
   

    for (int ir = 0; ir < W * H * 4; ir++) //Set Alpha=255
        pixels[ir] = 255;

    for (int ix = 0; ix < W; ix++) //Generate any image
        CreateImage(ix, 0, 720);




    while (window.isOpen())
    {
        //Again, stuff used to draw image on screen (found online)
        //Why this part is so slow??
        //Is possible to speed up things mantaining the "pixel array"?
        //(i like have the single pixle draw control)
        texture.update(pixels);
        window.draw(sprite);
        window.display();
    }
    return 0;
}

« Last Edit: June 26, 2023, 10:40:09 pm by LakySimi1 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10821
    • View Profile
    • development blog
    • Email
540fps is neither slow in an absolute nor relative sense, that's 1.85ms per frame!
There's no display that can even show you that many frames per second. :D

Don't forget that FPS is non-linear. So the framerate will drop a faster rate than the frametime.

Using texture.update is the fastest way SFML can update pixel data. I don't know if OpenGL offers any other methods, but again, at 540fps you're not having any performance issue and shouldn't try to find faster ways.
The results you get aren't even representative and can be influenced by any kind of background work.

If you want fast pixel manipulation, then that's what fragment shaders were created for. Your math and manipulation is directly executed on the GPU in a vectorized manner. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Don't forget, also, that if you aren't changing every pixel on every frame, you can update just a part of the texture - as required - allowing you to updates just the parts that actually change.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

LakySimi1

  • Newbie
  • *
  • Posts: 25
    • View Profile
540fps is neither slow in an absolute nor relative sense, that's 1.85ms per frame!
There's no display that can even show you that many frames per second. :D

Don't forget that FPS is non-linear. So the framerate will drop a faster rate than the frametime.

Using texture.update is the fastest way SFML can update pixel data. I don't know if OpenGL offers any other methods, but again, at 540fps you're not having any performance issue and shouldn't try to find faster ways.
The results you get aren't even representative and can be influenced by any kind of background work.

If you want fast pixel manipulation, then that's what fragment shaders were created for. Your math and manipulation is directly executed on the GPU in a vectorized manner. ;)

I may agree with you, is a lot more fps than needed for pretty much everything, but comparing to  sf::RectangleShape, which, perform a lot better makes me doubt about the "general correctness" of the method presented in the code provided for what i want to achieve (pixel per pixel "hand painting", for something like a raycaster wolfenstein-like engine for example, so 60 complete windows update per second).. but, if you assure me that the code method is foundamentally right i will use it.
Unfortunately i don't know about fragment shader (or any shader)..

Thank you both for your reply! :)
« Last Edit: June 27, 2023, 11:04:32 pm by LakySimi1 »

 

anything