我有以下程序,它创建一个 SFML 窗口并使用
SetLayeredWindowAttributes
和 LWA_COLORKEY
启用色度键,然后在 5 秒后禁用它。
#include <iostream>
#include "SFML/Graphics.hpp"
#include <windows.h>
static void enableWindowChromaKey(sf::RenderWindow* window, sf::Color chromaKeyColour)
{
HWND windowHWND = window->getSystemHandle();
SetWindowLongPtr(windowHWND, GWL_EXSTYLE, GetWindowLongPtr(windowHWND, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(windowHWND, RGB(chromaKeyColour.r, chromaKeyColour.g, chromaKeyColour.b), 255, LWA_COLORKEY);
}
static void disableWindowChromaKey(sf::RenderWindow* window)
{
HWND windowHWND = window->getSystemHandle();
SetWindowLongPtr(windowHWND, GWL_EXSTYLE, GetWindowLongPtr(windowHWND, GWL_EXSTYLE) & ~WS_EX_LAYERED);
}
int main()
{
sf::RenderWindow renderWindow;
renderWindow.create(sf::VideoMode(1280, 720), "Transparency Test");
enableWindowChromaKey(&renderWindow, sf::Color::Red); // If this is commented out ~80 FPS
sf::CircleShape redCircle = sf::CircleShape(250.0f);
redCircle.setOrigin(250.0f, 250.0f);
redCircle.setPosition(640.0f, 360.0f);
redCircle.setFillColor(sf::Color::Red);
sf::Clock clock;
sf::Clock timer;
while (renderWindow.isOpen())
{
if (timer.getElapsedTime().asSeconds() > 5.0f)
{
disableWindowChromaKey(&renderWindow); // Does not return to ~80 FPS if chroma-key is enabled prior
}
float deltaT = clock.restart().asSeconds();
std::cout << 1 / deltaT << std::endl;
sf::Event e;
while (renderWindow.pollEvent(e))
{
if (e.type == sf::Event::Closed)
{
renderWindow.close();
}
}
renderWindow.clear();
for (int i = 0; i < 5000; i++)
{
renderWindow.draw(redCircle);
}
renderWindow.display();
}
}
色度键透明度以及启用和禁用它的功能可以正常工作,但启用色度键会导致性能大幅下降,从大约 80 FPS 降至 45 FPS。这是可以理解的,但我遇到的问题是,使用
disableWindowChromaKey
后,程序不会返回到 80 FPS,而是保持在 45 FPS,所以我假设 renderWindow
中的某些内容没有正确重置。
我尝试过使用
InvalidateRect(windowHWND, nullptr, TRUE)
和 UpdateWindow(windowHWND)
RedrawWindow(windowHWND, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN)
renderWindow.resetGlStates()
但这些选项都不起作用。知道禁用色度键后导致性能保持较低水平的原因以及如何解决此问题吗?
我发现禁用色度键后调整窗口大小可以修复性能问题。我不确定为什么会出现这种情况,但解决此问题的方法是简单地强制窗口更改大小,然后再将其改回来。
static void disableWindowChromaKey(sf::RenderWindow* window)
{
HWND windowHWND = window->getSystemHandle();
SetWindowLongPtr(windowHWND, GWL_EXSTYLE, GetWindowLongPtr(windowHWND, GWL_EXSTYLE) & ~WS_EX_LAYERED);
window->setSize(sf::Vector2u(window->getSize().x + 1, window->getSize().y));
window->setSize(sf::Vector2u(window->getSize().x - 1, window->getSize().y));
}