diff --git a/VisualC/SDL.sln b/VisualC/SDL.sln index b5cf786ae2..d6e894049e 100644 --- a/VisualC/SDL.sln +++ b/VisualC/SDL.sln @@ -131,6 +131,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "01-joystick-polling", "exam EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "02-joystick-events", "examples\input\02-joystick-events\02-joystick-events.vcxproj", "{FCBDF2B2-1129-49AE-9406-3F219E65CA89}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsoftwaretransparent", "tests\testsoftwaretransparent\testsoftwaretransparent.vcxproj", "{D91C45E2-274E-4C0F-89C7-9986F9A7E85A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -579,6 +581,14 @@ Global {FCBDF2B2-1129-49AE-9406-3F219E65CA89}.Release|Win32.Build.0 = Release|Win32 {FCBDF2B2-1129-49AE-9406-3F219E65CA89}.Release|x64.ActiveCfg = Release|x64 {FCBDF2B2-1129-49AE-9406-3F219E65CA89}.Release|x64.Build.0 = Release|x64 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Debug|Win32.ActiveCfg = Debug|Win32 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Debug|Win32.Build.0 = Debug|Win32 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Debug|x64.ActiveCfg = Debug|x64 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Debug|x64.Build.0 = Debug|x64 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Release|Win32.ActiveCfg = Release|Win32 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Release|Win32.Build.0 = Release|Win32 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Release|x64.ActiveCfg = Release|x64 + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -644,6 +654,7 @@ Global {3DB9B219-769E-43AC-8B8B-319DB6045DCF} = {D1BF59F6-22DC-493B-BDEB-451A50DA793D} {B3852DB7-E925-4026-8B9D-D2272EFEFF3C} = {8DEAE483-FDE7-463F-9FD5-F597BBAED1F9} {FCBDF2B2-1129-49AE-9406-3F219E65CA89} = {8DEAE483-FDE7-463F-9FD5-F597BBAED1F9} + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C320C9F2-1A8F-41D7-B02B-6338F872BCAD} diff --git a/VisualC/tests/testsoftwaretransparent/testsoftwaretransparent.vcxproj b/VisualC/tests/testsoftwaretransparent/testsoftwaretransparent.vcxproj new file mode 100644 index 0000000000..1970a3b334 --- /dev/null +++ b/VisualC/tests/testsoftwaretransparent/testsoftwaretransparent.vcxproj @@ -0,0 +1,209 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {D91C45E2-274E-4C0F-89C7-9986F9A7E85A} + testsoftwaretransparent + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/testsoftwaretransparent.tlb + + + %(AdditionalOptions) /utf-8 + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/testsoftwaretransparent.tlb + + + %(AdditionalOptions) /utf-8 + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/testsoftwaretransparent.tlb + + + %(AdditionalOptions) /utf-8 + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/testsoftwaretransparent.tlb + + + %(AdditionalOptions) /utf-8 + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + $(TreatWarningsAsError) + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} + false + false + true + + + + + + + + + \ No newline at end of file diff --git a/src/video/windows/SDL_windowsframebuffer.c b/src/video/windows/SDL_windowsframebuffer.c index f2bbd590a9..d9af714bfc 100644 --- a/src/video/windows/SDL_windowsframebuffer.c +++ b/src/video/windows/SDL_windowsframebuffer.c @@ -59,6 +59,9 @@ bool WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS); DeleteObject(hbm); + // Check if a transparent channel is required + bool need_alpha = (window->flags & SDL_WINDOW_TRANSPARENT) != 0; + *format = SDL_PIXELFORMAT_UNKNOWN; if (info->bmiHeader.biCompression == BI_BITFIELDS) { int bpp; @@ -68,16 +71,22 @@ bool WIN_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL masks = (Uint32 *)((Uint8 *)info + info->bmiHeader.biSize); *format = SDL_GetPixelFormatForMasks(bpp, masks[0], masks[1], masks[2], 0); } - if (*format == SDL_PIXELFORMAT_UNKNOWN) { - // We'll use RGB format for now - *format = SDL_PIXELFORMAT_XRGB8888; + if (*format == SDL_PIXELFORMAT_UNKNOWN || need_alpha) { + // We'll use RGB or BGRA32 format for now + *format = need_alpha ? SDL_PIXELFORMAT_BGRA32 : SDL_PIXELFORMAT_XRGB8888; // Create a new one SDL_memset(info, 0, size); info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = 32; - info->bmiHeader.biCompression = BI_RGB; + info->bmiHeader.biCompression = need_alpha ? BI_BITFIELDS : BI_RGB; + + if (need_alpha) { + int tmpbpp; + Uint32 *bgr32masks = (Uint32 *)((Uint8 *)info + info->bmiHeader.biSize); + SDL_GetMasksForPixelFormat(SDL_PIXELFORMAT_BGRA32, &tmpbpp, &bgr32masks[0], &bgr32masks[1], &bgr32masks[2], &bgr32masks[3]); + } } // Fill in the size information diff --git a/test/testsoftwaretransparent.c b/test/testsoftwaretransparent.c new file mode 100644 index 0000000000..bd22d09f5a --- /dev/null +++ b/test/testsoftwaretransparent.c @@ -0,0 +1,155 @@ +/* + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +#include +#include + +#include "glass.h" + + +int main(int argc, char *argv[]) +{ + const char *image_file = NULL; + SDL_Window *window = NULL; + SDL_Renderer *renderer = NULL; + SDL_Texture *texture = NULL; + SDL_WindowFlags flags; + bool done = false; + SDL_Event event; + + int return_code = 1; + + + int windowWidth = 800; + int windowHeight = 600; + SDL_FRect destRect; + destRect.x = 0; + destRect.y = 0; + destRect.w = 100; + destRect.h = 100; + + SDL_FRect destRect2; + destRect2.x = 700; + destRect2.y = 0; + destRect2.w = 100; + destRect2.h = 100; + + SDL_FRect destRect3; + destRect3.x = 0; + destRect3.y = 500; + destRect3.w = 100; + destRect3.h = 100; + + SDL_FRect destRect4; + destRect4.x = 700; + destRect4.y = 500; + destRect4.w = 100; + destRect4.h = 100; + + SDL_FRect destRect5; + destRect5.x = 350; + destRect5.y = 250; + destRect5.w = 100; + destRect5.h = 100; + + + /* Create the window hidden */ + flags = (SDL_WINDOW_HIDDEN | SDL_WINDOW_TRANSPARENT); + //flags |= SDL_WINDOW_BORDERLESS; + + window = SDL_CreateWindow("SDL Software Renderer Transparent Test", windowWidth, windowHeight, flags); + if (!window) { + SDL_Log("Couldn't create transparent window: %s", SDL_GetError()); + goto quit; + } + + /* Create a software renderer and set the blend mode */ + renderer = SDL_CreateRenderer(window, SDL_SOFTWARE_RENDERER); + if (!renderer) { + SDL_Log("Couldn't create renderer: %s", SDL_GetError()); + goto quit; + } + + if (!SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND)) { + SDL_Log("Couldn't set renderer blend mode: %s\n", SDL_GetError()); + return false; + } + + /* Create texture and set the blend mode */ + // texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, windowWidth, windowHeight); + //texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, windowWidth, windowHeight); + // texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_TARGET, windowWidth, windowHeight); + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGRA8888, SDL_TEXTUREACCESS_TARGET, windowWidth, windowHeight); + if (texture == NULL) { + SDL_Log("Couldn't create texture: %s\n", SDL_GetError()); + return false; + } + + if (!SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND_PREMULTIPLIED)) { + SDL_Log("Couldn't set texture blend mode: %s\n", SDL_GetError()); + return false; + } + + /* Show */ + SDL_ShowWindow(window); + + /* We're ready to go! */ + while (!done) { + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_EVENT_KEY_DOWN: + if (event.key.key == SDLK_ESCAPE) { + done = true; + } + break; + case SDL_EVENT_QUIT: + done = true; + break; + default: + break; + } + } + + + /* Draw opaque red squares at the four corners of the form, and draw a red square with an alpha value of 180 in the center of the form */ + + SDL_SetRenderTarget(renderer, texture); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderFillRect(renderer, &destRect); + SDL_RenderFillRect(renderer, &destRect2); + SDL_RenderFillRect(renderer, &destRect3); + SDL_RenderFillRect(renderer, &destRect4); + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 180); + SDL_RenderFillRect(renderer, &destRect5); + + SDL_SetRenderTarget(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + SDL_RenderTexture(renderer, texture, NULL, NULL); + + /* Show everything on the screen and wait a bit */ + SDL_RenderPresent(renderer); + SDL_Delay(100); + } + + /* Success! */ + return_code = 0; + +quit: + SDL_DestroyTexture(texture); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + return return_code; +}