Vector graphics on textures with Gizeh (Cairo)

Thanks to ThomasEgi for pointing out that Gizeh is a thing that exists.

from direct.showbase.ShowBase import ShowBase
from panda3d.core import PNMImage, Texture
from panda3d.core import PTAUchar
from panda3d.core import CardMaker

import numpy as np
import cairo
import gizeh as gz
import random

s = ShowBase()

image_x_size = 512
image_y_size = 512

# Quad in scene, to display the image on
input_img = PNMImage(image_x_size, image_y_size)  # It's RGB.
input_tex = Texture()
input_tex.load(input_img)
screen = render.attach_new_node(CardMaker('in_scene_screen').generate())
screen.set_pos(-0.5, 2, -0.5)
screen.set_texture(input_tex)

# Gizeh setup
surface = gz.Surface(image_x_size, image_y_size)


def update_gizeh_image():
    star1 = gz.star(radius=70, ratio=.4, fill=(1,1,1), angle=-np.pi/2,
                    stroke_width=2, stroke=(1,0,0))
    star2 = gz.star(radius=55, ratio=.4, fill=(1,0,0), angle=-np.pi/2)
    # Gizeh coords are right-down.
    stars = gz.Group([star1, star2]).translate([random.randint(100,412),
                                                random.randint(100,412)])
    stars.draw(surface)


def gizeh_image(task):
    update_gizeh_image()
    # Why does this need to be copied? That might be expensive!
    #   Some manipulations apparently make an array non-viable for transfer, and
    #   that includes even an out-of-the-box gizeh surface.
    # Why the [::-1,:,::-1]?
    #   Inverting the x axis (texture space uses up-right coords), and transform
    #   the color space from BGR to RGB.
    input_tex.set_ram_image(PTAUchar(surface.get_npimage()[::-1,:,::-1].copy()))
    return task.cont


base.taskMgr.add(gizeh_image, "gizeh to screen", sort=45)

s.run()

…and now let’s see about matplotlib…