Frage

I currently have some code that draws using pycairo and renders to an SDL surface by way of PyGame. This works nicely on Linux and Windows but the Mac is giving me headaches. Everything just comes out blue or pink The byte order seems to be BGRA instead of ARGB and I have tried using pygame.Surface.set_masks and set_shifts to no avail. This is only broken on the mac (osx 10.6):

import cairo
import pygame

width = 300
height = 200

pygame.init()
pygame.fastevent.init()
clock = pygame.time.Clock()
sdl_surface = pygame.display.set_mode((width, height))

c_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(c_surface)

while True:
    pygame.fastevent.get()
    clock.tick(30)
    ctx.rectangle(10, 10, 50, 50)
    ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0)
    ctx.fill_preserve()

    dest = pygame.surfarray.pixels2d(sdl_surface)
    dest.data[:] = c_surface.get_data()
    pygame.display.flip()

I can fix it with array slicing or using PIL but this kills my frame rate. Is there a way to do this in-place or with settings?

War es hilfreich?

Lösung

After a lot of hair tearing I have a workaround that does not hurt my frame rate too much by simply reversing the array:

import cairo
import pygame

width = 300
height = 200

pygame.init()
pygame.fastevent.init()
clock = pygame.time.Clock()
sdl_surface = pygame.display.set_mode((width, height))

c_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(c_surface)

while True:
    pygame.fastevent.get()
    clock.tick(30)
    ctx.rectangle(10, 10, 50, 50)
    ctx.set_source_rgba(1.0, 0.0, 0.0, 1.0)
    ctx.fill_preserve()

    dest = pygame.surfarray.pixels2d(sdl_surface)
    dest.data[:] = c_surface.get_data()[::-1]
    tmp = pygame.transform.flip(sdl_surface, True, True)
    sdl_surface.fill((0,0,0))    #workaround to clear the display
    del dest     #this is needed to unlock the display surface
    sdl_surface.blit(tmp, (0,0))
    pygame.display.flip()

The fact that I have to delete the array and blit from a temporary Surface does not seem right but it was the only way to flip the display. If anyone has a cleaner suggestion here, please comment.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top