My goal is to be able to drag polygons around a screen when I click and hold somewhere on the screen. I have created some polygons in Python SDL2. I added some basic animation, so when I drag my mouse, the polygons move too.
This results in continuously reusing the previous buffer.
If I clear the buffer before every frame of animation, the polygons flicker as they render in order from top to bottom. If the movement is fast enough, they don't even have time to render.
I have tried rendering with
renderflags = (
sdl2.SDL_RENDERER_ACCELERATED | sdl2.SDL_RENDERER_PRESENTVSYNC
)
I thought this would improve performance, but it made it worse.
How can I avoid the flicker?
This is the part of the code that handles the click input, and clears the buffer:
grid = new_hex_grid(edge_size, font, radius, x_offset, y_offset)
grid.render(renderer)
# Wait for the user to close the window
running = True
mousedown_start_position = None
previous_touch_down_position = None
while running:
for event in sdl2.ext.get_events():
if event.type == sdl2.SDL_QUIT:
running = False
elif event.type == sdl2.SDL_MOUSEBUTTONDOWN:
# print(event.motion.x, event.motion.y)
print("hi")
mousedown_start_position = (event.motion.x, event.motion.y)
previous_touch_down_position = mousedown_start_position
elif event.type == sdl2.SDL_MOUSEMOTION:
if mousedown_start_position:
pass
renderer.clear(0)
# print(event.motion.x, event.motion.y)
grid.move_to(grid.x + event.motion.x - previous_touch_down_position[0],
grid.y + event.motion.y - previous_touch_down_position[1])
grid.render(renderer)
previous_touch_down_position = (event.motion.x, event.motion.y)
elif event.type == sdl2.SDL_MOUSEBUTTONUP:
mousedown_start_position = None
# Do all animations here
# Refresh the screen
renderer.present()
# Clean up
sdl2.ext.quit()
This is how I render the hexagon from a separate hexagon class
color = (50, 150, 50, 255)
# Convert the vertex lists to arrays of c_int16
x_array = (ctypes.c_int16 * vertex_count)(*vx)
y_array = (ctypes.c_int16 * vertex_count)(*vy)
# Draw the filled box
sdl2.sdlgfx.filledPolygonRGBA(renderer.sdlrenderer, x_array, y_array, vertex_count, *color)
This is the class that class the collection of hexagons
class HexGrid(Renderable):
def __init__(self, font, radius, hexagons_by_idx, x, y):
self.radius = radius
self.font = font
self.x = x
self.y = y
self.hexagons_by_idx = hexagons_by_idx
def move_to(self, x, y):
self.x = x
self.y = y
def render(self, renderer: sdl2.ext.Renderer):
font_offset_x = self.radius / 2 + self.x
font_offset_y = self.radius / 3 + self.y
font_block_width = self.radius
left_corner_index = 3
for idx, hexagon in self.hexagons_by_idx.items():
hexagon.move_to(self.x, self.y)
hexagon.render(renderer)
render_font(self.font, font_block_width,
hexagon.vertices[left_corner_index][0] + font_offset_x,
hexagon.vertices[left_corner_index][1] + font_offset_y, renderer,
f"{idx[0]}, {idx[1]}")