pygame-ce icon indicating copy to clipboard operation
pygame-ce copied to clipboard

`BLEND_OVERLAY` blend mode

Open itzpr3d4t0r opened this issue 2 years ago • 2 comments
trafficstars

Closes #2373, featuring: BLEND_OVERLAY and BLEND_RGB_OVERLAY flags and algorithm with:

  • 1 pixel at a time implementation that's hardware agnostic
  • 8 pixels at a time with AVX2
  • 4 pixels at a time with SSE2

For a visual test i'm using the following image and program: base

import pygame

pygame.init()
TEXT_COLOR = "black"
screen = pygame.display.set_mode((1000, 500))

img = pygame.image.load("base.png").convert()
img = pygame.transform.scale(img, (250, 250))

background = pygame.Surface(img.get_size())
background.fill((255, 100, 50))

background2 = pygame.Surface(img.get_size())
background2.fill((255, 0, 100))

font = pygame.font.SysFont("Arial", 28, True)
BLEND_OVERLAY = font.render("OVERLAY", True, TEXT_COLOR)
BLEND_ADD = font.render("ADD", True, TEXT_COLOR)
BLEND_MULT = font.render("MULT", True, TEXT_COLOR)
BASE = font.render("BASE", True, TEXT_COLOR)
MIN = font.render("MIN", True, TEXT_COLOR)
MAX = font.render("MAX", True, TEXT_COLOR)
SUB = font.render("SUB", True, TEXT_COLOR)

keep = True
clock = pygame.Clock()

while keep:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            keep = False

    screen.blits(
        [
            (img, (0, 250)),
            (img, (250, 250)),
            (img, (500, 250)),
            (img, (750, 250)),
            (img, (0, 0)),
            (img, (250, 0)),
            (img, (500, 0)),
            (img, (750, 0)),
            (background, (0, 0), None, pygame.BLEND_OVERLAY),
            (background, (250, 0), None, pygame.BLEND_ADD),
            (background, (500, 0), None, pygame.BLEND_MULT),
            (background, (250, 250), None, pygame.BLEND_MIN),
            (background, (500, 250), None, pygame.BLEND_MAX),
            (background, (750, 250), None, pygame.BLEND_SUB),
            (BLEND_OVERLAY, BLEND_OVERLAY.get_rect(center=(125, 20))),
            (BLEND_ADD, BLEND_ADD.get_rect(center=(375, 20))),
            (BLEND_MULT, BLEND_MULT.get_rect(center=(625, 20))),
            (BASE, BASE.get_rect(center=(125, 270))),
            (MIN, MIN.get_rect(center=(375, 270))),
            (MAX, MAX.get_rect(center=(625, 270))),
            (SUB, SUB.get_rect(center=(875, 270))),
        ]
    )

    pygame.display.flip()

Summary by CodeRabbit

  • New Features
    • Added an Overlay blending mode (BLEND_OVERLAY, BLEND_RGB_OVERLAY) for RGB/RGBA surfaces, exposed to the public API and stubs.
  • Performance
    • Hardware-accelerated overlay paths on supported CPUs (SSE2/AVX2) with software fallbacks for other configurations.
  • Documentation
    • Special Flags List updated with Overlay description, formula, and version note (2.5.6).
  • Tests
    • New tests validating overlay blending on 24-bit and 32-bit surfaces.

itzpr3d4t0r avatar Aug 04 '23 16:08 itzpr3d4t0r