Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Square distortion during window resizing problem

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.

like image 400
werwer werwer Avatar asked Aug 07 '26 17:08

werwer werwer


1 Answers

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.

like image 55
Ahmed AEK Avatar answered Aug 09 '26 05:08

Ahmed AEK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!