c++ - SDL:全屏半透明背景

标签 c++ sdl transparency

我正在尝试编写一个具有覆盖整个屏幕的半透明背景的程序。经过一些研究后,SDL 似乎是可行的方法。

我编写了代码来创建一个全屏窗口,其背景的 alpha 等于 100(满分 255),但由于某种原因它只绘制纯色。我做错了什么?

// Initialise SDL
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        this->throwSDLError("SDL_Init Error");
}

// Create the window and renderer
if (SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP, &(this->window), &(this->renderer)) != 0) {
        this->throwSDLError("Could not create the window and renderer");
}

// Set the blend mode to specify how the alpha channel is used
if (SDL_SetRenderDrawBlendMode(this->renderer, SDL_BLENDMODE_BLEND) != 0) {
        this->throwSDLError("Could not set render draw blend mode");
}

// Set the colour to draw
if (SDL_SetRenderDrawColor(this->renderer, 200, 200, 200, 100) != 0) {
        this->throwSDLError("Could not set the drawing colour");
}

// Clear the screen using the colour
if (SDL_RenderClear(this->renderer) != 0) {
        this->throwSDLError("Could not render the screen");
}

// Present the rendered screen
SDL_RenderPresent(this->renderer);

最佳答案

在 Windows 上,您可以使用 SetLayeredWindowAttributes 创建透明窗口从无边界 SDL 窗口对背景色进行色度键控。

代码:

// SDL window with transparent background v1.2
#include <SDL.h>
#include <SDL_syswm.h>
#include <Windows.h>

// Makes a window transparent by setting a transparency color.
bool MakeWindowTransparent(SDL_Window* window, COLORREF colorKey) {
    // Get window handle (https://stackoverflow.com/a/24118145/3357935)
    SDL_SysWMinfo wmInfo;
    SDL_VERSION(&wmInfo.version);  // Initialize wmInfo
    SDL_GetWindowWMInfo(window, &wmInfo);
    HWND hWnd = wmInfo.info.win.window;

    // Change window type to layered (https://stackoverflow.com/a/3970218/3357935)
    SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);

    // Set transparency color
    return SetLayeredWindowAttributes(hWnd, colorKey, 0, LWA_COLORKEY);
}

int main(int argc, char** argv) {
    // Get resolution of primary monitor
    int desktopWidth = GetSystemMetrics(SM_CXSCREEN);
    int desktopHeight = GetSystemMetrics(SM_CYSCREEN);

    SDL_Window* window = SDL_CreateWindow("SDL Transparent Window",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        desktopWidth, desktopHeight, SDL_WINDOW_BORDERLESS);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    // Set background color to magenta and clear screen
    SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
    SDL_RenderClear(renderer);

    // Draw blue square in top-left corner
    SDL_Rect rect1 = {0, 0, 100, 100};
    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
    SDL_RenderFillRect(renderer, &rect1);

    // Draw red square in center of the screen
    SDL_Rect rect2 = {(desktopWidth-100)/2, (desktopHeight-100)/2, 100, 100};
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
    SDL_RenderFillRect(renderer, &rect2);

    // Add window transparency (Magenta will be see-through)
    MakeWindowTransparent(window, RGB(255, 0, 255));

    // Render the square to the screen
    SDL_RenderPresent(renderer);

    // Loop until user quits
    bool quit = false;
    SDL_Event event;
    while (!quit) {
       while (SDL_PollEvent(&event) != 0) {
           if (event.type == SDL_QUIT) {
               quit = true;
           }
       }
    }

    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

结果:

Transparent sdl window with two squares

解释:

首先,创建一个覆盖整个桌面的无边框窗口。选择纯色遮蔽色并将其用作背景。 (在我的例子中,我使用了洋红色)。然后您可以使用 Win32 API 函数 SetLayeredWindowAttributes 键入您的掩码颜色.

具有这种颜色的窗口的任何部分都将完全透明。程序后面的其他窗口可以正常交互。默认情况下,其他应用程序可以移动到无边框窗口的顶部。

如果您希望您的 SDL 窗口始终位于其他窗口之上,您可以在创建窗口时设置 SDL_WINDOW_ALWAYS_ON_TOP 标志。

另见

关于c++ - SDL:全屏半透明背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23048993/

相关文章:

c++ - 使用 std::future 无效使用不完整类型

c++ - 如何在 Windows Mobile 平台中使用 C++ 在 Excel 工作表中绘制图形?

c - 尝试让进程在没有 SDL(感知到的)崩溃的情况下运行 C

c++ - CMake - 同时为 Windows 和 Linux 开发

c++ - Mix_Halt 特定音轨?

CSS 以渐变样式创建 CSS3 透明叠加层

python - Kivy 截图,背景清晰

java - Android:使默认全息按钮不透明

c++ - 全局使用的 Typedef 变量?

c++ - shared_ptr<T> 到 shared_ptr<T const> 和 vector<T> 到 vector<T const>