如何解决SDL 2 中带有不透明元素的完全透明窗口
我正在尝试创建一个本身完全透明的 SDL 窗口,但是当图像被渲染到它上面时,图像是完全不透明的并且图像的 alpha 通道被保留(因此图像的透明像素仍然存在)透明的)。所以结果将只是屏幕上的图像,周围没有容器(想象一下在屏幕上贴一张真实的贴纸)
这里是简化代码:
#include <stdio.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_syswm.h>
#include <iostream>
#include <Windows.h>
#include <string>
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Texture* image;
int imageWidth = 0;
int imageHeight = 0;
bool init()
{
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("SDL could not initialize! SDL Error: %s\n",SDL_GetError());
return false;
}
//Set texture filtering to linear
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"1"))
{
printf("Warning: Linear texture filtering not enabled!");
}
//Create window
window = SDL_CreateWindow("SDL Tutorial",SDL_WINDOWPOS_UNDEFINED,500,300,SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS);
if (window == NULL)
{
printf("Window could not be created! SDL Error: %s\n",SDL_GetError());
return false;
}
//Create renderer for window
renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL)
{
printf("Renderer could not be created! SDL Error: %s\n",SDL_GetError());
return false;
}
//Initialize renderer color
SDL_SetRenderDrawColor(renderer,255,255);
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %s\n",IMG_GetError());
return false;
}
return true;
}
bool loadImage(const std::string& path)
{
//The final texture
SDL_Texture* newImage = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (!loadedSurface)
{
printf("Unable to load image %s! SDL_image Error: %s\n",path.c_str(),IMG_GetError());
return false;
}
//Create texture from surface pixels
newImage = SDL_CreateTextureFromSurface(renderer,loadedSurface);
if (!newImage)
{
printf("Unable to create texture from %s! SDL Error: %s\n",SDL_GetError());
return false;
}
imageWidth = loadedSurface->w;
imageHeight = loadedSurface->h;
//Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
image = newImage;
return true;
}
void displayImage()
{
SDL_SetRenderDrawColor(renderer,255);
SDL_RenderClear(renderer);
SDL_SetWindowSize(window,imageWidth,imageHeight);
SDL_Rect renderQuad = { 0,imageHeight };
SDL_RenderCopy(renderer,image,NULL,&renderQuad);
SDL_RenderPresent(renderer);
}
// Makes a window transparent by setting a transparency color.
bool windowColorKey(SDL_Window* window,COLORREF colorKey) {
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version); // Initialize wmInfo
SDL_GetWindowWMInfo(window,&wmInfo);
HWND hWnd = wmInfo.info.win.window;
// Change window type to layered
SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE) | WS_EX_LAYERED);
// Set transparency color
return SetLayeredWindowAttributes(hWnd,colorKey,LWA_COLORKEY);
}
int main(int argc,char* args[]) {
// Initialize SDL: Create a window and renderer
init();
// Load the image
loadImage("example.png");
// Color key the background of the window (magenta)
windowColorKey(window,RGB(255,255));
// Render the image on the widnow with magenta for backround color
displayImage();
// Check for events
bool windowActive = true;
SDL_Event event;
while (windowActive)
{
while (SDL_PollEvent(&event) != 0)
{
if (event.type == SDL_QUIT || event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { windowActive = false; }
}
}
return 0;
}
使用 SDL_SetWindowOpacity() 将不起作用,因为窗口的所有元素也是透明的。
目前我知道实现这一目标的唯一方法是使用颜色键控,但不幸的是它效果不佳,因为某些图像将包含您用于颜色键控的颜色,另外图像将具有您用于图像周围颜色键控的颜色的小边框。它很薄但很烦人。
我正在考虑以其他方式使用分层窗口的功能,但找不到或不知道如何使用。
那么,问题是如何让窗口本身完全透明,同时又可以完全控制窗口元素的透明度?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。