I tried to make a square that maintains its size and aspect ratio during window resizing using SDL3 and SDL_SetRenderLogicalPresentation()
with the SDL_LOGICAL_PRESENTATION_LETTERBOX
mode:
import sdl3
# Function to draw a square
def draw_square(renderer, x, y, size):
sdl3.SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) # White color
rect = sdl3.SDL_FRect(x=x, y=y, w=size, h=size)
sdl3.SDL_RenderFillRect(renderer, rect)
# Initialize SDL3
if sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO) < 0:
print(f"SDL initialization error: {sdl3.SDL_GetError().decode()}")
exit(1)
# Create window
window = sdl3.SDL_CreateWindow(b"Hello World", 640, 480, sdl3.SDL_WINDOW_RESIZABLE)
if not window:
print(f"Window creation error: {sdl3.SDL_GetError().decode()}")
exit(1)
# Create renderer
renderer = sdl3.SDL_CreateRenderer(window, b"metal")
if not renderer:
print(f"Renderer creation error: {sdl3.SDL_GetError().decode()}")
exit(1)
# Set logical rendering size
logical_width, logical_height = 640, 480
sdl3.SDL_SetRenderLogicalPresentation(renderer, logical_width, logical_height, sdl3.SDL_LOGICAL_PRESENTATION_LETTERBOX)
# Parameters for positioning the square
square_size = 100 # Fixed square size
square_x = (logical_width - square_size) / 2 # Center horizontally
square_y = (logical_height - square_size) / 2 # Center vertically
running = True
while running:
# Event handling
event = sdl3.SDL_Event()
while sdl3.SDL_PollEvent(event):
if event.type == sdl3.SDL_EVENT_QUIT:
running = False
# Rendering
sdl3.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255) # Black background
sdl3.SDL_RenderClear(renderer)
# Draw square with fixed size and centered position
draw_square(renderer, square_x, square_y, square_size)
sdl3.SDL_RenderPresent(renderer)
# Cleanup
sdl3.SDL_DestroyRenderer(renderer)
sdl3.SDL_DestroyWindow(window)
sdl3.SDL_Quit()
Currently, the square only resets to its original width and height after I release the mouse button (when resizing ends). During the resizing process itself, the square gets stretched or squashed — it deforms.
Is this the expected behavior of SDL_SetRenderLogicalPresentation? How can I make the square that never deforms at all, no matter how the window is resized? Are there workarounds or best practices for this? (Mac user)
For example, would converting the square into a texture or something similar help keep its aspect ratio stable during resizing?
My code written in Python but feel free to answer in any programming language, main goal is to get the way how to do window resizing without distortion.
you should use the SDL Main Callbacks API it can be done from python
import os, ctypes, time
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
import sdl3
renderer = ctypes.POINTER(sdl3.SDL_Renderer)()
window = ctypes.POINTER(sdl3.SDL_Window)()
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s", sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
if not sdl3.SDL_CreateWindowAndRenderer("Hello, World!".encode(), 640, 480, sdl3.SDL_WINDOW_RESIZABLE, window, renderer):
sdl3.SDL_Log("Couldn't create window/renderer: %s", sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_SetRenderVSync(renderer, 1)
# Set logical rendering size
logical_width, logical_height = 640, 480
sdl3.SDL_SetRenderLogicalPresentation(renderer, logical_width, logical_height,
sdl3.SDL_LOGICAL_PRESENTATION_LETTERBOX)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
def draw_square(renderer, x, y, size):
sdl3.SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) # White color
rect = sdl3.SDL_FRect(x=x, y=y, w=size, h=size)
sdl3.SDL_RenderFillRect(renderer, rect)
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
# Rendering
sdl3.SDL_SetRenderDrawColor(renderer, 120, 0, 0, 255) # Red background
sdl3.SDL_RenderClear(renderer)
# Set logical rendering size
logical_width, logical_height = 640, 480
# Parameters for positioning the square
square_size = 100 # Fixed square size
square_x = (logical_width - square_size) / 2 # Center horizontally
square_y = (logical_height - square_size) / 2 # Center vertically
# Draw square with fixed size and centered position
draw_square(renderer, square_x, square_y, square_size)
sdl3.SDL_RenderPresent(renderer)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
... # SDL will clean up the window/renderer for us.
you can now resize the window without distorting the box.
the reason this works is because you give SDL3 your draw function, and SDL3 will call it when it sees the window being resized.