Browse Source

SDL3: Fix nearest-neighbor scaling

For some reason, setting the scaling on just `texture` still results
in bluriness. However, setting the default scaling mode on the renderer
fixes it.

Also, does a few more things the SDL3 way.
pull/8230/head
Gleb Mazovetskiy 5 months ago committed by Anders Jenbo
parent
commit
705a007c22
  1. 22
      Source/engine/dx.cpp
  2. 2
      Source/hwcursor.cpp
  3. 41
      Source/utils/display.cpp
  4. 2
      Source/utils/sdl_compat.h

22
Source/engine/dx.cpp

@ -242,29 +242,15 @@ void RenderPresent()
#ifndef USE_SDL1 #ifndef USE_SDL1
if (renderer != nullptr) { if (renderer != nullptr) {
#ifdef USE_SDL3
if (!SDL_UpdateTexture(texture.get(), nullptr, surface->pixels, surface->pitch)) ErrSdl();
#else
if (SDL_UpdateTexture(texture.get(), nullptr, surface->pixels, surface->pitch) <= -1) ErrSdl();
#endif
// Clear buffer to avoid artifacts in case the window was resized
// TODO only do this if window was resized
#ifdef USE_SDL3 #ifdef USE_SDL3
if (!SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255)) ErrSdl(); if (!SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255)) ErrSdl();
#else
if (SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255) <= -1) ErrSdl();
#endif
#ifdef USE_SDL3
if (!SDL_RenderClear(renderer)) ErrSdl(); if (!SDL_RenderClear(renderer)) ErrSdl();
#else if (!SDL_UpdateTexture(texture.get(), nullptr, surface->pixels, surface->pitch)) ErrSdl();
if (SDL_RenderClear(renderer) <= -1) ErrSdl();
#endif
#ifdef USE_SDL3
if (!SDL_RenderTexture(renderer, texture.get(), nullptr, nullptr)) ErrSdl(); if (!SDL_RenderTexture(renderer, texture.get(), nullptr, nullptr)) ErrSdl();
#else #else
if (SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255) <= -1) ErrSdl();
if (SDL_RenderClear(renderer) <= -1) ErrSdl();
if (SDL_UpdateTexture(texture.get(), nullptr, surface->pixels, surface->pitch) <= -1) ErrSdl();
if (SDL_RenderCopy(renderer, texture.get(), nullptr, nullptr) <= -1) ErrSdl(); if (SDL_RenderCopy(renderer, texture.get(), nullptr, nullptr) <= -1) ErrSdl();
#endif #endif

2
Source/hwcursor.cpp

@ -144,7 +144,7 @@ bool SetHardwareCursorFromSurface(SDL_Surface *surface, HotpointPosition hotpoin
size.width, size.height, scaledSize.width, scaledSize.height); size.width, size.height, scaledSize.width, scaledSize.height);
#endif #endif
#ifdef USE_SDL3 #ifdef USE_SDL3
SDL_BlitSurfaceScaled(converted.get(), nullptr, scaledSurface.get(), nullptr, SDL_SCALEMODE_NEAREST); SDL_BlitSurfaceScaled(converted.get(), nullptr, scaledSurface.get(), nullptr, SDL_SCALEMODE_PIXELART);
#else #else
SDL_BlitScaled(converted.get(), nullptr, scaledSurface.get(), nullptr); SDL_BlitScaled(converted.get(), nullptr, scaledSurface.get(), nullptr);
#endif #endif

41
Source/utils/display.cpp

@ -432,19 +432,21 @@ void AdjustToScreenGeometry(Size windowSize)
float GetDpiScalingFactor() float GetDpiScalingFactor()
{ {
#ifdef USE_SDL1 #ifdef USE_SDL3
return 1.0F; const float dispScale = SDL_GetWindowDisplayScale(ghMainWnd);
#else if (dispScale == 0.0F) {
LogError("SDL_GetWindowDisplayScale: {}", SDL_GetError());
SDL_ClearError();
return 1.0F;
}
return dispScale;
#elif !defined(USE_SDL1)
if (renderer == nullptr) if (renderer == nullptr)
return 1.0F; return 1.0F;
int renderWidth; int renderWidth;
int renderHeight; int renderHeight;
#ifdef USE_SDL3
SDL_GetCurrentRenderOutputSize(renderer, &renderWidth, &renderHeight);
#else
SDL_GetRendererOutputSize(renderer, &renderWidth, &renderHeight); SDL_GetRendererOutputSize(renderer, &renderWidth, &renderHeight);
#endif
int windowWidth; int windowWidth;
int windowHeight; int windowHeight;
@ -454,6 +456,8 @@ float GetDpiScalingFactor()
const float vhfactor = static_cast<float>(renderHeight) / windowHeight; const float vhfactor = static_cast<float>(renderHeight) / windowHeight;
return std::min(hfactor, vhfactor); return std::min(hfactor, vhfactor);
#else
return 1.0F;
#endif #endif
} }
@ -616,7 +620,11 @@ bool SpawnWindow(const char *lpWindowName)
} }
#ifdef USE_SDL3 #ifdef USE_SDL3
ghMainWnd = SDL_CreateWindow(lpWindowName, windowSize.width, windowSize.height, flags); if (*GetOptions().Graphics.upscale) {
if (!SDL_CreateWindowAndRenderer(lpWindowName, windowSize.width, windowSize.height, flags, &ghMainWnd, &renderer)) ErrSdl();
} else {
ghMainWnd = SDL_CreateWindow(lpWindowName, windowSize.width, windowSize.height, flags);
}
#else #else
ghMainWnd = SDL_CreateWindow(lpWindowName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowSize.width, windowSize.height, flags); ghMainWnd = SDL_CreateWindow(lpWindowName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowSize.width, windowSize.height, flags);
#endif #endif
@ -687,14 +695,17 @@ void ReinitializeTexture()
if (renderer == nullptr) if (renderer == nullptr)
return; return;
auto quality = StrCat(static_cast<int>(*GetOptions().Graphics.scaleQuality));
#ifdef USE_SDL3 #ifdef USE_SDL3
texture = SDLWrap::CreateTexture(renderer, DEVILUTIONX_DISPLAY_TEXTURE_FORMAT, SDL_TEXTUREACCESS_STREAMING, gnScreenWidth, gnScreenHeight); if (!SDL_SetDefaultTextureScaleMode(renderer,
if (quality == "nearest") { *GetOptions().Graphics.scaleQuality == ScalingQuality::NearestPixel
SDL_SetTextureScaleMode(texture.get(), SDL_SCALEMODE_NEAREST); ? SDL_SCALEMODE_PIXELART
: SDL_SCALEMODE_LINEAR)) {
Log("SDL_SetDefaultTextureScaleMode: {}", SDL_GetError());
SDL_ClearError();
} }
texture = SDLWrap::CreateTexture(renderer, DEVILUTIONX_DISPLAY_TEXTURE_FORMAT, SDL_TEXTUREACCESS_STREAMING, gnScreenWidth, gnScreenHeight);
#else #else
auto quality = StrCat(static_cast<int>(*GetOptions().Graphics.scaleQuality));
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, quality.c_str()); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, quality.c_str());
texture = SDLWrap::CreateTexture(renderer, DEVILUTIONX_DISPLAY_TEXTURE_FORMAT, SDL_TEXTUREACCESS_STREAMING, gnScreenWidth, gnScreenHeight); texture = SDLWrap::CreateTexture(renderer, DEVILUTIONX_DISPLAY_TEXTURE_FORMAT, SDL_TEXTUREACCESS_STREAMING, gnScreenWidth, gnScreenHeight);
#endif #endif
@ -756,8 +767,6 @@ void ReinitializeRenderer()
SDL_RenderSetVSync(renderer, *GetOptions().Graphics.frameRateControl == FrameRateControl::VerticalSync ? 1 : 0); SDL_RenderSetVSync(renderer, *GetOptions().Graphics.frameRateControl == FrameRateControl::VerticalSync ? 1 : 0);
#endif #endif
ReinitializeTexture();
#ifdef USE_SDL3 #ifdef USE_SDL3
if (!SDL_SetRenderLogicalPresentation(renderer, gnScreenWidth, gnScreenHeight, if (!SDL_SetRenderLogicalPresentation(renderer, gnScreenWidth, gnScreenHeight,
*GetOptions().Graphics.integerScaling *GetOptions().Graphics.integerScaling
@ -775,6 +784,8 @@ void ReinitializeRenderer()
} }
#endif #endif
ReinitializeTexture();
#ifdef USE_SDL3 #ifdef USE_SDL3
RendererTextureSurface = SDLSurfaceUniquePtr { SDL_CreateSurface(gnScreenWidth, gnScreenHeight, texture->format) }; RendererTextureSurface = SDLSurfaceUniquePtr { SDL_CreateSurface(gnScreenWidth, gnScreenHeight, texture->format) };
if (RendererTextureSurface == nullptr) ErrSdl(); if (RendererTextureSurface == nullptr) ErrSdl();

2
Source/utils/sdl_compat.h

@ -236,7 +236,7 @@ inline const SDL_GamepadDeviceEvent &SDLC_EventGamepadDevice(const SDL_Event &ev
#define SDLC_SURFACE_BITSPERPIXEL(surface) surface->format->BitsPerPixel #define SDLC_SURFACE_BITSPERPIXEL(surface) surface->format->BitsPerPixel
inline bool SDLC_PushEvent(SDL_Event *event) { return SDL_PushEvent(event) == 0; } inline bool SDLC_PushEvent(SDL_Event *event) { return SDL_PushEvent(event) == 1; }
inline inline
#ifdef USE_SDL1 #ifdef USE_SDL1

Loading…
Cancel
Save