You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SFML渐变矩形右侧缺失三角区域问题求助

SFML渐变背景右侧缺失三角区域问题修复

问题描述

使用SFML实现窗口背景渐变矩形时,渐变无法铺满整个窗口,屏幕右侧存在一块未被覆盖的三角空白区域。

问题代码

void setBackgroundGradient(sf::RenderWindow& window) {
    // Create a vertex array for the background
    sf::VertexArray background(sf::Quads, 4);

    // Define the gradient colors
    sf::Color colorLeft(117, 58, 136);
    sf::Color colorRight(174, 50, 111);

    // Set the gradient colors and positions for each vertex
    for (int i = 0; i < 4; ++i) {
        // Set the position for each vertex
        background[i].position = sf::Vector2f((i % 2) * window.getSize().x, (i / 2) * window.getSize().y);

        // Interpolate color between colorLeft and colorRight based on the x-position percentage
        float factor = background[i].position.x / window.getSize().x;

        background[i].color = sf::Color(
            static_cast<sf::Uint8>((1.0f - factor) * colorLeft.r + factor * colorRight.r),
            static_cast<sf::Uint8>((1.0f - factor) * colorLeft.g + factor * colorRight.g),
            static_cast<sf::Uint8>((1.0f - factor) * colorLeft.b + factor * colorRight.b)
        );
    }

    window.draw(background);
}


void createWindow() {
    sf::RenderWindow window{ sf::VideoMode(1200,800), "TGUI window with SFML"}; //{1200, 800}

    //A Gui Object that works with Sfml window. 
    tgui::GuiSFML gui{ window };

    runGUI(gui, window);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            gui.handleEvent(event);

            if (event.type == sf::Event::Closed)
                window.close();
        }

        //Set background color and display window
        //window.clear(sf::Color(50,50,50));

        window.clear();

        setBackgroundGradient(window);

        gui.draw();

        window.display();

    }
}

问题原因

问题出在顶点顺序不符合SFML绘制Quad的规则。SFML绘制Quad时,要求顶点按顺时针顺序排列(左上→右上→右下→左下),但当前循环生成的顶点顺序是:

  • i=0: (0, 0) → 左上
  • i=1: (窗口宽度, 0) → 右上
  • i=2: (0, 窗口高度) → 左下
  • i=3: (窗口宽度, 窗口高度) → 右下

这种跳跃式的顶点顺序会导致SFML将Quad拆分为两个三角形时绘制错乱,从而产生右侧的空白三角区域。

修复方案

调整顶点的位置赋值逻辑,确保四个顶点严格按左上→右上→右下→左下的顺时针顺序排列:

void setBackgroundGradient(sf::RenderWindow& window) {
    sf::VertexArray background(sf::Quads, 4);
    sf::Color colorLeft(117, 58, 136);
    sf::Color colorRight(174, 50, 111);
    sf::Vector2u windowSize = window.getSize();

    // 按顺时针顺序定义Quad的四个顶点
    background[0].position = sf::Vector2f(0, 0);                  // 左上
    background[1].position = sf::Vector2f(windowSize.x, 0);       // 右上
    background[2].position = sf::Vector2f(windowSize.x, windowSize.y); // 右下
    background[3].position = sf::Vector2f(0, windowSize.y);       // 左下

    // 为每个顶点计算渐变颜色
    for (int i = 0; i < 4; ++i) {
        float factor = background[i].position.x / windowSize.x;
        background[i].color = sf::Color(
            static_cast<sf::Uint8>((1.0f - factor) * colorLeft.r + factor * colorRight.r),
            static_cast<sf::Uint8>((1.0f - factor) * colorLeft.g + factor * colorRight.g),
            static_cast<sf::Uint8>((1.0f - factor) * colorLeft.b + factor * colorRight.b)
        );
    }

    window.draw(background);
}

额外提示

  • SFML的Quads图元对顶点顺序有严格要求,必须是连续的顺时针或逆时针排列,否则会出现绘制异常。
  • 直接显式指定每个顶点的位置,比通过循环计算更直观,也能避免顺序错误。

内容的提问来源于stack exchange,提问作者Viggx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:40:31