C++ SDL:全屏半透明背景

C++ SDL:全屏半透明背景,c++,sdl,transparency,C++,Sdl,Transparency,我试图写一个程序,有一个半透明的背景覆盖整个屏幕。经过一些研究,SDL似乎是一条可行之路 我已经编写了创建一个全屏窗口的代码,背景的alpha值等于100(255中的100),但出于某种原因,它只绘制纯色。我做错了什么 // Initialise SDL if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { this->throwSDLError("SDL_Init Error"); } // Create the window and re

我试图写一个程序,有一个半透明的背景覆盖整个屏幕。经过一些研究,SDL似乎是一条可行之路

我已经编写了创建一个全屏窗口的代码,背景的alpha值等于100(255中的100),但出于某种原因,它只绘制纯色。我做错了什么

// 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上,可以通过使用对无边框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;
}
//具有透明背景的SDL窗口v1.2
#包括
#包括
#包括
//通过设置透明度颜色使窗口透明。
bool使窗口透明(SDL_窗口*窗口,COLORREF colorKey){
//拿窗把手(https://stackoverflow.com/a/24118145/3357935)
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.VERSION);//初始化wmInfo
SDL_GetWindowWMInfo(窗口和wmInfo);
HWND HWND=wmInfo.info.win.window;
//将窗口类型更改为“分层”(https://stackoverflow.com/a/3970218/3357935)
SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE)| WS_EX_分层);
//设置透明度颜色
返回SetLayeredWindowAttributes(hWnd、colorKey、0、LWA_colorKey);
}
int main(int argc,字符**argv){
//获取主监视器的分辨率
int desktopWidth=GetSystemMetrics(SM_CXSCREEN);
int desktopHeight=GetSystemMetrics(SM\u CYSCREEN);
SDL_Window*Window=SDL_CreateWindow(“SDL透明窗口”,
SDL_WINDOWPOS_居中,SDL_WINDOWPOS_居中,
桌面宽度、桌面高度、SDL_窗口(无边框);
SDL_渲染器*渲染器=SDL_CreateRenderer(窗口,-1,SDL_渲染器加速);
//将背景色设置为洋红色并清除屏幕
SDL_SetRenderDrawColor(渲染器,255,0,255,255);
SDL_渲染器(渲染器);
//在左上角画蓝色正方形
SDL_Rect rect1={0,0,100,100};
SDL_SetRenderDrawColor(渲染器,0、0、255、255);
SDL_RenderFillRect(渲染器和rect1);
//在屏幕中央画红方块
SDL_Rect rect2={(桌面宽度-100)/2,(桌面高度-100)/2100};
SDL_SetRenderDrawColor(渲染器,255,0,0,255);
SDL_RenderFillRect(渲染器和rect2);
//添加窗口透明度(洋红将透明)
使WindowTransparent(窗口,RGB(255,0,255));
//将正方形渲染到屏幕上
SDL_渲染器呈现(渲染器);
//循环直到用户退出
bool-quit=false;
SDL_事件;
而(!退出){
while(SDL_PollEvent(&event)!=0){
if(event.type==SDL\u QUIT){
退出=真;
}
}
}
SDL_窗口(窗口);
SDL_退出();
返回0;
}
结果:

// 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;
}

说明:

// 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函数键入遮罩颜色

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

如果希望SDL窗口始终位于其他窗口的顶部,则可以在创建窗口时设置
SDL\u window\u always\u on\u top
标志

另见
  • 堆栈溢出:
  • 堆栈溢出:
  • 微软:

要绘制部分不透明的背景以查看其他窗口和下方的桌面吗?我不相信SDL(或任何其他类型的抽象库)能够做到这一点。您需要访问特定于平台的窗口库(例如Windows、Mac/Cocoa、Linux/Xorg),但跨平台库可以将对setWindowTransparency方法的调用转换为平台的相应本机调用。谢谢,是否也有方法使矩形单击通过?因此,当您单击矩形时,它不会抓住焦点。我知道这是一条旧注释,但您(或其他带着相同问题来到这里的人)可能希望看看如何实现回调以返回
SDL\u HitTestResult
,并使用
SDL\u SetWindowHitTest
使窗口使用它。(,)谢谢@Stevoisiak这太棒了:)