如何设置SDL窗口背景为透明(优先平台无关实现)
如何设置SDL窗口背景为透明(优先平台无关实现)
嘿,我来帮你搞定这个SDL窗口透明的需求!要让窗口背景变成透明,能看到后面的桌面,我们可以先尝试平台无关的方案,如果在特定系统上不生效,再考虑平台特定的补充方法。
平台无关的实现步骤
SDL2本身提供了支持透明窗口的API,只需要对你的代码做几处小修改:
创建窗口时添加透明标志
在调用SDL_CreateWindowAndRenderer的时候,把窗口标志参数从0改成SDL_WINDOW_TRANSPARENT,这个标志会告诉系统我们需要一个支持透明背景的窗口。调整渲染清除的颜色为完全透明
原来的代码里用红色填充整个窗口,现在我们要把清除颜色改成完全透明的黑色(RGBA: 0, 0, 0, 0),这样渲染清除后窗口背景就是透明的,不会遮挡后面的内容。确保渲染器支持透明
创建渲染器的时候尽量使用硬件加速的渲染器(默认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
相关产品推荐
相关产品推荐

