简体   繁体   English

如何用颜色填充 sf::TriangleStrip 的 sf::VertexArray?

[英]How to fill sf::VertexArray of sf::TriangleStrip with color?

I would like to increase the drawing performance by using a single sf::VertexArray to display thousands of circles.我想通过使用单个sf::VertexArray来显示数千个圆来提高绘图性能。 To make sure it works, I wrote this example:为了确保它有效,我写了这个例子:

#include <SFML/Graphics.hpp>
#include <iostream>

#define WIDTH 100
#define HEIGHT 100

int main() {
    sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "RTREE",
                            sf::Style::Close);
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) window.close();
        }

        sf::CircleShape circle(50);
        circle.setPosition(100,100);
        size_t count = circle.getPointCount();
        sf::VertexArray objects(sf::TriangleStrip, count);
        for (int i = 0; i < count; i++) {
           objects.append(circle.getPoint(i));

        }
        for (int i = 0; i < objects.getVertexCount(); i++) {
            objects[i].color = sf::Color::Blue;
        }

        window.clear();
        window.draw(objects);
        window.display();
    }
}

However, the color only applies to the line, not the fill:但是, color仅适用于线条,不适用于填充:

在此处输入图像描述

Is it possible to fill the shape with a single color?是否可以用单一颜色填充形状?

You are right, displaying more than 1000 circles with a window.draw between each of them result in poor performances.你是对的,显示超过 1000 个圆圈,每个圆圈之间有一个window.draw会导致性能不佳。 The vertexArray is indeed a good solution. vertexArray 确实是一个很好的解决方案。

You used sf::TriangleStrip which does not work as you expected.您使用的sf::TriangleStrip无法按预期工作。 Your verticles are indeed painted, but they are only on the edge of the circle.你的verticles确实画了,但它们只在圆圈的边缘。 You need to use either sf::TriangleFan or sf::Triangles if you want more than one circle per array.如果您希望每个数组有多个圆,则需要使用sf::TriangleFansf::Triangles

Here an example.这是一个例子。 I was able to display 513'000 verticles at 60 fps (each circle is about 30 verticles, which is about 10'000 circles.我能够以 60 fps 的速度显示 513'000 个 Verticles(每个圆圈大约有 30 个 Verticle,即大约 10'000 个圆圈。

#include <SFML/Graphics.hpp>
#include <cmath>
#include <iostream>
#include <sstream>
#define WIDTH 800
#define HEIGHT 800
using namespace std;

template <typename T>
std::string to_string_with_precision(const T a_value, const int n = 6)
{
    std::ostringstream out;
    out.precision(n);
    out << std::fixed << a_value;
    return out.str();
}

void addCircle(sf::VertexArray &array, sf::Vector2f position, float radius, sf::Color color) {
    size_t count = 30;

    for (int i = 0; i < count; i += 1) {
        sf::Vertex v0;
        v0.position = sf::Vector2f(position.x, position.y);
        v0.color = color;
        array.append(v0);

        sf::Vertex v1;
        float angle = i * 2 * M_PI / count;
        v1.position = sf::Vector2f(position.x + cos(angle) * radius, position.y + sin(angle) * radius);
        v1.color = color;
        array.append(v1);

        sf::Vertex v2;
        angle = (i + 1) * 2 * M_PI / count;
        v2.position = sf::Vector2f(position.x + cos(angle) * radius, position.y + sin(angle) * radius);
        v2.color = color;
        array.append(v2);
    }
}

#define FRAMERATE 120

int main() {
    sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "RTREE", sf::Style::Close);

    // Fps text
    sf::Font font;
    if (!font.loadFromFile("../assets/collegiate.ttf")) {
        std::cout << "Error loading font" << std::endl;
    }
    sf::Text fps;
    fps.setFont(font);
    fps.setPosition(10, 10);
    fps.setCharacterSize(16);
    fps.setFillColor(sf::Color::White);

    // Time management
    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;
    sf::Time timePerFrame = sf::seconds(1.f / FRAMERATE);
    sf::Time timeSinceLastDraw = sf::Time::Zero;
    window.setFramerateLimit(FRAMERATE);

    float vr = 0;

    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) window.close();
        }

        size_t count = 15;
        sf::Color color = sf::Color::Red;
        color.a = 50;
        sf::Color color2 = sf::Color::Blue;
        color2.a = 20;

        sf::VertexArray objects(sf::Triangles);

        for (int k = 0; k < 5; k++) {
            sf::Color c = k % 2 ? color : color2;

            for (int j = 20; j < 400; j += 5) {
                for (int i = 0; i < count; i++) {
                    float angle = i * 2 * M_PI / count;
                    angle += (i % 2 ? vr : -vr) * k * (k % 2 ? 1 : -1);
                    addCircle(objects, sf::Vector2f(WIDTH / 2 + cos(angle) * j, HEIGHT / 2 + sin(angle) * j), j / 5, c);
                }
            }
        }


        timeSinceLastDraw = clock.restart();
        timeSinceLastUpdate += timeSinceLastDraw;
        double timeFps = 1.f / timeSinceLastDraw.asSeconds();
        fps.setString("verticles: " + to_string_with_precision(objects.getVertexCount(), 0) + " fps: " + to_string_with_precision(timeFps, 0));

        while (timeSinceLastUpdate > timePerFrame) {
            timeSinceLastUpdate -= timePerFrame;
            vr += 0.01;
        }

        window.clear();
        window.draw(objects);
        window.draw(fps);
        window.display();
    }
}

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM