SFML community forums

Help => General => Topic started by: abcd1234567 on January 01, 2024, 07:16:00 pm

Title: window.display() is very slow with vertex array
Post by: abcd1234567 on January 01, 2024, 07:16:00 pm
I'm trying to run a small piece of code, just to get familier with VertexArray:
#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

#define CELL_SIZE 32

void fillVertexArray(sf::VertexArray& va, int num_of_squares_x, int num_of_squares_y){
    for (int i = 0; i < num_of_squares_y; i++){
        for (int j = 0; j < num_of_squares_x; j++){
            va.append(sf::Vector2f((float)j * CELL_SIZE, (float)i * CELL_SIZE));
            va.append(sf::Vector2f((float)(j + 1) * CELL_SIZE, (float)i));
            va.append(sf::Vector2f((float)(j + 1) * CELL_SIZE, (float)(i + 1) * CELL_SIZE));
            va.append(sf::Vector2f((float)j, (float)(i + 1) * CELL_SIZE));
        }
    }

}

void printLogTime(sf::Clock& code_timer, bool reset){
    if (reset) code_timer.restart();
    else std::cout << code_timer.getElapsedTime().asMilliseconds() << std::endl;
}

int main() {
    sf::VertexArray va(sf::PrimitiveType::Quads);
    fillVertexArray(va, 32, 32);

    sf::RenderWindow window(sf::VideoMode(1440, 810), "SFML test", sf::Style::Default);
    float zoom = 1;
    sf::View view = window.getDefaultView();
    sf::Clock code_timer;

    while(true){
        sf::Event evnt;
        while (window.pollEvent(evnt)){
            switch(evnt.type){
                case sf::Event::Closed:
                    return -1;

                case sf::Event::MouseWheelScrolled:
                    // &#39;zoom()&#39; is by a factor. a number greater than 1 means zoom-out; a number smaller than 1 means zoom-in.
                    if (evnt.mouseWheelScroll.delta <= -1) { // Scroll down - zoom-out
                        zoom = std::min(2.0, zoom + 0.1); // By using &#39;min&#39; with &#39;2&#39;, we set it as a lower limit.
                    }
                    else if (evnt.mouseWheelScroll.delta >= 1) { // Scroll up - zoom-in
                        zoom = std::max(0.5, zoom - 0.1); // By using &#39;max&#39; with &#39;0.5&#39;, we set it as an upper limit.
                    }

                    // We use &#39;setSize()&#39; here to reset our view (by setting it to the default view&#39;s size).
                    // Why? Because, as we&#39;ve said, &#39;zoom()&#39; is by a factor. So if we zoomed twice we&#39;d be multiplying instead of adding.
                    // For that we reset the view and then apply the zoom on it.
                    view.setSize(window.getDefaultView().getSize()); // Reset the size
                    view.zoom(zoom);
                    window.setView(view);
                    break;
            }
        }

        window.clear();
        window.draw(va);
        printLogTime(code_timer, true);
        window.display();
        printLogTime(code_timer, false);
    }

    return 0;
}
 

But when logging I get that every window.display() call takes about ~40 milliseconds.
When deleting the 'window.draw(va)' line, it drops down to 0 milliseconds (rounding).
For comparison, in another project where there's a LOT of shapes on screen, it's also about 0 milliseconds, so I don't understand the sudden spike here, considering VertexArray should be very efficient
Title: Re: window.display() is very slow with vertex array
Post by: eXpl0it3r on January 02, 2024, 10:46:24 am
What platform are you on? Make sure your GPU drover is up-to-date.
Title: Re: window.display() is very slow with vertex array
Post by: abcd1234567 on January 02, 2024, 03:17:44 pm
What platform are you on? Make sure your GPU drover is up-to-date.

Windows 10, i5 gen 10 CPU with GTX 1650 GPU. Just updated my GPU drivers, and the problem persists :<
Title: Re: window.display() is very slow with vertex array
Post by: Hapax on January 02, 2024, 07:45:48 pm
I tested it as-is and only experienced time output (to console) of zero, sorry.

Oh, but I did notice that I don't think your squares are what you think they are.
Remember to multiply every component with CELL_SIZE. ;)
It shouldn't affect what display is doing but it should make what you see an actual grid of squares.
If you change the first vertex to this line, the error is a little more obvious:
va.append({ sf::Vector2f((float)j * CELL_SIZE, (float)i * CELL_SIZE), sf::Color::Red });
Title: Re: window.display() is very slow with vertex array
Post by: abcd1234567 on January 02, 2024, 08:27:08 pm
I tested it as-is and only experienced time output (to console) of zero, sorry.

Oh, but I did notice that I don't think your squares are what you think they are.
Remember to multiply every component with CELL_SIZE. ;)
It shouldn't affect what display is doing but it should make what you see an actual grid of squares.
If you change the first vertex to this line, the error is a little more obvious:
va.append({ sf::Vector2f((float)j * CELL_SIZE, (float)i * CELL_SIZE), sf::Color::Red });

Of course, my mistake.
But how peculiar, when changing it to the correct way (multipling every component with CELL_SIZE), the problem is resolved.

Before the change:
(https://i.ibb.co/6RsbNcL/1.png)

After the change:
(https://i.ibb.co/mGxxp0t/2.png)

Well, thanks a lot :>
Title: Re: window.display() is very slow with vertex array
Post by: Hapax on January 02, 2024, 09:27:15 pm
Aw, nice to see that that fixed it. :)

Not sure why but maybe your particular driver is not happy with all of those quads sharing so many vertices and gets confused when trying to decide which one it should be ???