I have the following program which creates a SFML window and enables chroma-key using SetLayeredWindowAttributes
with LWA_COLORKEY
, then disables it after 5 seconds.
#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();
}
}
The chroma-key transparency and the functions to enable and disable it work, but enabling chroma-key causes a reasonably large drop in performance from about 80 FPS to 45 FPS. This is understandable, but the issue I'm having is that after using disableWindowChromaKey
the program does not return to 80 FPS and instead stays at 45 FPS, so I'm assuming something in renderWindow
isn't being reset properly.
I've tried using
InvalidateRect(windowHWND, nullptr, TRUE)
and UpdateWindow(windowHWND)
RedrawWindow(windowHWND, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN)
renderWindow.resetGlStates()
But none of these options have worked. Any idea what's causing the performance to stay low after chroma-key has been disabled and how to fix this?
I found that resizing the window after chroma-key has been disabled fixes the performance issues. I'm not sure why this is the case, but a workaround for this issue is to simply force the window to change size and then change it back.
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));
}