簡體   English   中英

SFML 怎么這么快?

[英]How is SFML so fast?

我需要在窗口上逐個像素地用 C++ 繪制一些圖形。 為了做到這一點,我創建了一個 SFML 窗口、精靈和紋理。 我將所需的圖形繪制到 uint8_t 數組,然后用它更新紋理和精靈。 這個過程大約需要2500 us 繪制兩個填充整個窗口的三角形只需要10 us 這種巨大的差異怎么可能? 我已經嘗試多線程逐像素繪制,但兩個數量級的差異仍然存在。 我還嘗試使用點圖繪制像素,但沒有任何改進。 我知道 SFML 在后台使用一些 GPU 加速,但簡單地循環並將值分配給像素陣列已經需要數百微秒。

有誰知道在窗口中分配像素值的更有效方法?

這是我用來比較三角形和逐像素繪制速度的代碼示例:

#include <SFML/Graphics.hpp>
#include <chrono>
using namespace std::chrono;
#include <iostream>
#include<cmath>

uint8_t* pixels;

int main(int, char const**)
{
    const unsigned int width=1200;
    const unsigned int height=1200;
    sf::RenderWindow window(sf::VideoMode(width, height), "MA: Rasterization Test");
    pixels = new uint8_t[width*height*4];
    sf::Texture pixels_texture;
    pixels_texture.create(width, height);
    sf::Sprite pixels_sprite(pixels_texture);
    sf::Clock clock;
    sf::VertexArray triangle(sf::Triangles, 3);

    triangle[0].position = sf::Vector2f(0, height);
    triangle[1].position = sf::Vector2f(width, height);
    triangle[2].position = sf::Vector2f(width/2, height-std::sqrt(std::pow(width,2)-std::pow(width/2,2)));
    triangle[0].color = sf::Color::Red;
    triangle[1].color = sf::Color::Blue;
    triangle[2].color = sf::Color::Green;
    
    
    while (window.isOpen()){
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
            if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
                window.close();
            }
        }

        window.clear(sf::Color(255,255,255,255));

        // Pixel-by-pixel
        int us = duration_cast< microseconds >(system_clock::now().time_since_epoch()).count();
        for(int i=0;i!=width*height*4;++i){
            pixels[i]=255;
        }
        pixels_texture.update(pixels);
        window.draw(pixels_sprite);
        int duration=duration_cast< microseconds >(system_clock::now().time_since_epoch()).count()-us;
        std::cout<<"Background: "<<duration<<" us\n";

        // Triangle
        us = duration_cast< microseconds >(system_clock::now().time_since_epoch()).count();
        window.draw(triangle);
         duration=duration_cast< microseconds >(system_clock::now().time_since_epoch()).count()-us;
        std::cout<<"Triangle: "<<duration<<" us\n";

        window.display();
    }
    return EXIT_SUCCESS;
}

使用顯卡在現代設備中繪制圖形,繪制速度取決於您發送到圖形內存的數據中有多少三角形。 這就是為什么只畫兩個三角形很快。

正如您提到的多線程,如果您使用OpenGL(我不記得SFML使用什么,但應該是一樣的),您認為您在繪制的基本上是將命令和數據發送到顯卡,所以這里的多線程不是很有用,圖形卡有自己的線程來執行此操作。

如果您對顯卡的工作原理感到好奇,那么教程就是您應該閱讀書。

PS 當你編輯你的問題時,我猜持續時間 2500us vs 10us 是因為你 for 循環創建了一個紋理(即使紋理是純白色背景)(和 for 循環,你可能需要在 for 循環之后開始計數) , 將紋理發送到顯卡需要時間,而繪制三角形只發送幾個點。 盡管如此,我還是建議閱讀教程,逐個像素地創建紋理可能會證明對 GPU 工作原理的誤解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM