SDL: Fullscreen translucent background

SDL: Fullscreen translucent background



I'm trying to write a program that has a translucent background covering the whole screen. After some research it appeared that SDL would be the way to go.



I've written the code to create a full screen window with a background whose alpha is equal to 100 (out of 255), but for some reason it just draws the solid colour. What have I done wrong?


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





You want to draw the background with partial opacity to see other windows and your desktop underneath? I don't believe SDL (or any other kind of abstraction library) would be able to do this. You'd need to access the platform-specific windowing library (e.g. Windows, Mac/Cocoa, Linux/Xorg)
– wavemode
Apr 13 '14 at 22:12





But a cross platform library could translate a call to a setWindowTransparency method into the appropriate native call for the platform.
– brnby
Apr 14 '14 at 21:07




1 Answer
1



On Windows, you can create a transparent window by using SetLayeredWindowAttributes to chroma-key the background color from a borderless SDL window.


SetLayeredWindowAttributes



Code:


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



Result:



Transparent sdl window with two squares



Explanation:



First, create a borderless window with that covers the entire desktop. Choose a solid masking color and use it as your background. (In my case, I used magenta). You can then key-out your masking color with the Win32 API function SetLayeredWindowAttributes.


SetLayeredWindowAttributes



Any part of the window with this color will be completely see-through. Other windows behind your program can be interacted with as normal. By default, other applications can be moved on top of your borderless window.



If you want your SDL window to always be on top of other windows, you can set the SDL_WINDOW_ALWAYS_ON_TOP flag when creating your window.


SDL_WINDOW_ALWAYS_ON_TOP






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)