[英]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.