pygame-ce
pygame-ce copied to clipboard
sdl2_video with blendmode_blend displays half transparent pixels incorrectly
trafficstars
When drawing textures unto other textures using the blend mode "blendmode_blend", it strongly reduces the opacity of half transparent pixels, instead of displaying them accurately.
I use pygame-ce 2.4.0 with python 3.10.
Here's a demonstration: The rotated space ship is glowing, because I drew it without any blendmode active. The upright space ship has lost it's glow because I drew it's texture on top of the first texture using pygame.Blendmode_blend
https://imgur.com/L8kOnkw
Sample code
import pygame, io, base64
from pygame._sdl2 import Renderer, Texture, Image, Window, messagebox
from time import perf_counter as get_ticks
import sys
tmp_image = pygame.image.load("Graphics/spaceship.png")
current = 0
def main():
global current
global fontsize
global font
pygame.init()
# We need a Window object and a Renderer
window = Window("SDL2", size=(1280, 720))
renderer = Renderer(window)
font = pygame.font.SysFont('Arial', 10)
fps = 0
fps_timestamp = get_ticks()
fps_t = Texture.from_surface(renderer, font.render('XXX', True, 'white'))
# ...converted into a Texure
img = Image(Texture.from_surface(renderer, tmp_image))
tex = Texture.from_surface(renderer, tmp_image)
img2 = Image(Texture.from_surface(renderer, tmp_image))
# Just some variables to let the image move around
scale = 1
scale_d = 0.0005
rotation = 0
# target = True allows us to render all stuff into this Texture before rendering it to the window
layer1 = Texture(renderer, (1280, 720), target=True)
layer2 = Texture(renderer, (1280, 720), target= True)
x2 = 100
y2 = 100
# keep track of the zoom level
zoom = 1
fade = 90
factor = 1
font = pygame.font.SysFont('Arial', round(30))
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT or e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
return
if e.type == pygame.MOUSEWHEEL:
if e.y > 0:
zoom += 0.1
else:
zoom -= 0.1
# Count the FPS
fps += 1
if get_ticks() - fps_timestamp > 1:
fps_timestamp = get_ticks()
fps_t = Texture.from_surface(renderer, font.render(str(fps) + ' FPS', True, 'white'))
fps = 0
# start rendering onto the buffer texture
# everything we do now with the renderer happens on that texture
renderer.target = layer1
renderer.clear()
scale = 1
img.angle=rotation%40 + 245
img.angle=265
img.origin = (520,130)
img.draw(dstrect=(50, 50, 247 * scale, 247 * scale))
renderer.target = layer2
renderer.clear()
scale = 1
img2.draw(dstrect=(450, 450, 247 * scale, 247 * scale))
# clear the screen
renderer.target = None
renderer.draw_color = "purple"
renderer.clear()
# draw the buffer Texure on the screen
renderer.draw_color = (0,0,0,0)
layer1.draw(dstrect=((1280 - 1280 * zoom) / 2, (720 - 720 * zoom) / 2, 1280 * zoom, 720 * zoom))
x, y = 1280,720
layer2.blend_mode = pygame.BLENDMODE_BLEND
layer2.draw(srcrect= (0,0, 1280, 720), dstrect=((1280 - 1280 * zoom) / 2, (720 - 720 * zoom) / 2, 1280 * zoom, 720 * zoom))
# print some stuff
zoom_t = Texture.from_surface(renderer, font.render(f'Zoom: {zoom:10.2f}', True, 'white'))
zoom_t.draw(dstrect=(520, 450, 100, 50))
# fps_t.draw()
fps_t.draw(dstrect=(10, 10, fps_t.width, fps_t.height))
# update the window, like pygame.display.flip() does
renderer.present()
main()