我正在尝试编写一个覆盖整个屏幕的半透明背景的程序。经过一些研究后,似乎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);
答案 0 :(得分:3)
在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;
}
结果:
说明:
首先,创建一个覆盖整个桌面的无边界窗口。选择纯色遮罩颜色并将其用作背景。 (就我而言,我使用了洋红色)。然后,您可以使用Win32 API函数SetLayeredWindowAttributes
来设置遮罩颜色。
带有该颜色的窗口的任何部分都将完全透明。程序后面的其他窗口可以正常进行交互。默认情况下,其他应用程序可以移动到无边界窗口的顶部。
如果您希望SDL窗口始终位于其他窗口之上,则可以在创建窗口时设置SDL_WINDOW_ALWAYS_ON_TOP
标志。