pygame_shaders icon indicating copy to clipboard operation
pygame_shaders copied to clipboard

[bug]the surface read from Shader.render lost its alpha value[solution provided]

Open MeteorShower2004 opened this issue 1 year ago • 0 comments

Describe the bug the surface returned by Shader.render method is always opaque (all pixels' alpha value are always 255)

To Reproduce 1.copy the code provided below, paste it into a file 2.put an image file with alpha values next to your source file 3.replace "{your_image}" in the provided source with the name of your image 4.run the source

(you can also try to change the alpha value of target_surface in glsl source, this bug also happens)

the source code is borrowed from file examples/water/main.py

import pygame
import pygame_shaders

pygame.init()
clock = pygame.time.Clock()
pygame.display.set_mode((600, 600), pygame.OPENGL | pygame.DOUBLEBUF)

display = pygame.Surface((600, 600))

screen_shader = pygame_shaders.DefaultScreenShader(display) # <- Here we supply our default display, it's this display which will be displayed onto the opengl context via the screen_shader

target_surface = pygame.image.load({your_image}), (0, 0))
shader = pygame_shaders.Shader(
    pygame_shaders.DEFAULT_VERTEX_SHADER, 
    pygame_shaders.DEFAULT_FRAGMENT_SHADER, 
    target_surface
) #<- give it to our shader

while True:
    display.fill((0, 255, 255))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            
    #our tested code
    display.blit(shader.render(), (0, 0))

    screen_shader.render() 

    pygame.display.flip()
    clock.tick(30)

Expected behavior Assume the 1x1 image have a pixel with alpha 140, if you didn't modify its alpha in shader, the alpha of returned pixel should also be 140.

solution In file pygame_shaders.py line 160, just replace self.framebuffer.read() with self.framebuffer.read(components=4) and then add an 'A' to the end of the string "RGB". at last it looks like this:

surf​ ​=​ ​pygame​.​image​.​frombuffer​(​self​.​framebuffer​.​read​(components=4), ​self​.​target_surface​.​get_size​(), ​"RGBA"​)

(I edit this issues in my phone, so I'm sorry that if there's any issue)

MeteorShower2004 avatar May 05 '24 08:05 MeteorShower2004