Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alpha fillers #2682

Open
itzpr3d4t0r opened this issue Jan 21, 2024 · 0 comments
Open

Alpha fillers #2682

itzpr3d4t0r opened this issue Jan 21, 2024 · 0 comments
Labels

Comments

@itzpr3d4t0r
Copy link
Member

itzpr3d4t0r commented Jan 21, 2024

Recent updates in #2382, #2565 and #2566 have improved the speed of Surface.fill calls when using the ADD, SUB MULT, MIN and MAX blend flags. However, there’s still a fundamental issue with the fill function.

Currently, if no flags are used, the fill function simply replaces the surface pixels with the chosen color. If the color has an alpha value (and the surface is set up to support alpha), all surface pixels will adopt this alpha value, and no alpha blending will occur.

Consider this example:

import pygame

screen = pygame.display.set_mode((100, 100))

s = pygame.Surface((100, 100)).convert_alpha()
s.fill((100, 0, 100))  # all surface pixels are replaced with the solid color

print(s.get_at((0, 0)))  # outputs Color(100, 0, 100, 255)

# when we fill the surface with a transparent color, 
# the surface pixels are replaced again, not blended
s.fill((32, 32, 32, 100))

print(s.get_at((0, 0)))  # outputs Color(32, 32, 32, 100), which is incorrect

Using blit instead of fill gives different results:

import pygame

screen = pygame.display.set_mode((100, 100))

s = pygame.Surface((100, 100)).convert_alpha()
s.fill((100, 0, 100))  # surface pixels are replaced with the solid color
print(s.get_at((0, 0)))  # outputs Color(100, 0, 100, 255)

s2 = pygame.Surface((100, 100)).convert_alpha()
s2.fill((32, 32, 32, 100))
print(s2.get_at((0, 0)))  # outputs Color(32, 32, 32, 100)

s.blit(s2, (0, 0))
print(s.get_at((0, 0)))  # outputs Color(73, 12, 73, 255), the expected result

In terms of the C API implementation, adding this functionality directly (meaning when the blend_flag is 0) would conflict with the current setup, as it would be impossible to distinguish between wanting to blend with alpha or overwrite the pixel completely. Not to mention it could break back-compat.

A potential solution could be to add a specific blend flag for fill like FILL_BLEND. This would allow for an easy implementation of the three possible alpha blending algorithms.

So we would have something like this:

import pygame

screen = pygame.display.set_mode((100, 100))

s = pygame.Surface((100, 100)).convert_alpha()
s.fill((100, 0, 100))

s.fill((32, 32, 32, 100), special_flags=pygame.FILL_BLEND)

print(s.get_at((0, 0)))  # outputs Color(73, 12, 73, 255), which is correct
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant