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

如何设置SDL窗口背景为透明(优先平台无关实现)

如何设置SDL窗口背景为透明(优先平台无关实现)

嘿,我来帮你搞定这个SDL窗口透明的需求!要让窗口背景变成透明,能看到后面的桌面,我们可以先尝试平台无关的方案,如果在特定系统上不生效,再考虑平台特定的补充方法。

平台无关的实现步骤

SDL2本身提供了支持透明窗口的API,只需要对你的代码做几处小修改:

  1. 创建窗口时添加透明标志
    在调用SDL_CreateWindowAndRenderer的时候,把窗口标志参数从0改成SDL_WINDOW_TRANSPARENT,这个标志会告诉系统我们需要一个支持透明背景的窗口。

  2. 调整渲染清除的颜色为完全透明
    原来的代码里用红色填充整个窗口,现在我们要把清除颜色改成完全透明的黑色(RGBA: 0, 0, 0, 0),这样渲染清除后窗口背景就是透明的,不会遮挡后面的内容。

  3. 确保渲染器支持透明
    创建渲染器的时候尽量使用硬件加速的渲染器(默认SDL_CreateWindowAndRenderer会优先选硬件加速的),这样透明效果能正常工作。

修改后的完整代码

#include <Windows.h>
#include <stdlib.h>
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>

char g_buffer[100];

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str, int nWinMode) {

    SDL_Event event;
    SDL_Renderer* renderer = NULL;
    SDL_Texture* texture = NULL;
    SDL_Window* window = NULL;

    SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
    // 添加SDL_WINDOW_TRANSPARENT标志创建透明窗口
    SDL_CreateWindowAndRenderer(
        400, 400,
        SDL_WINDOW_TRANSPARENT, &window, &renderer
    );

    IMG_Init(IMG_INIT_PNG);

    texture = IMG_LoadTexture(renderer, "D:/Pobrane_2/flower.png");
    if (!texture)
    {
        sprintf(g_buffer, "IMG_LoadTexture error: %s\n", SDL_GetError());
        MessageBox(NULL, g_buffer, "Error!", MB_OK | MB_ICONINFORMATION);
        g_buffer[0] = 0;
        return 1;
    }

    while (1) {
        // 设置清除颜色为完全透明的黑色
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
        // 用透明色清除窗口
        SDL_RenderClear(renderer);
        // 渲染PNG图片
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
        if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
            break;
    }
    SDL_DestroyTexture(texture);
    IMG_Quit();
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return EXIT_SUCCESS;
}

注意事项

  • SDL_WINDOW_TRANSPARENT标志在SDL2.0.1及以上版本才支持,如果你用的是旧版本,建议升级SDL。
  • 这个方案在Windows、macOS和大多数Linux桌面环境(比如GNOME、KDE)都能正常工作,但少数老旧的窗口管理器可能不支持透明窗口,这时候就需要用平台特定的方法。

平台特定的补充方案(以Windows为例)

如果平台无关的方法在Windows上不生效,可以用Win32 API手动设置窗口为分层透明窗口:
在创建窗口后,添加以下代码:

// 获取窗口句柄
HWND hwnd = SDL_GetWindowWMInfo(window)->info.win.window;
// 设置窗口扩展样式为分层窗口
SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// 设置透明色为黑色(和我们渲染清除的颜色对应),这样黑色区域会变成透明
SetLayeredWindowAttributes(hwnd, RGB(0,0,0), 0, LWA_COLORKEY);

这种方法是Windows特有的,会让窗口中所有和设置的透明色一致的区域都变成透明,适合兼容旧系统。

备注:内容来源于stack exchange,提问作者AlmondPudding

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 11:15:30