forked from mttu-developers/konabot
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""
|
||
headless moderngl
|
||
"""
|
||
import pathlib
|
||
import moderngl
|
||
import numpy as np
|
||
from PIL import Image
|
||
from konabot.plugins.marchtoy.scene import Scene
|
||
from nonebot import logger
|
||
|
||
PATH = pathlib.Path(__file__).parent / "shaders"
|
||
with (PATH / "vert.glsl").open(encoding='utf-8') as f:
|
||
VS_SRC = f.read()
|
||
|
||
async def render(command: str, res: tuple[int, int]):
|
||
fs = Scene(command).compile()
|
||
try:
|
||
ctx = moderngl.create_context(standalone=True)
|
||
except:
|
||
ctx = moderngl.create_context(standalone=True, backend="egl")
|
||
ctx.gc_mode = "auto"
|
||
try:
|
||
program = ctx.program(
|
||
vertex_shader=VS_SRC,
|
||
fragment_shader=fs
|
||
)
|
||
except Exception as e:
|
||
raise Exception(f"cannot compile glsl: {e}") from e
|
||
try:
|
||
uniform = program["u_resolution"]
|
||
except Exception as e:
|
||
raise Exception("无法获取 uniform,可能相机位于物体内部?")
|
||
uniform.write(np.array(res, dtype=np.float32))
|
||
vertices = np.array([-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0], dtype=np.float32)
|
||
indices = np.array([0, 1, 2, 1, 2, 3], dtype=np.int32)
|
||
ibo = ctx.buffer(indices)
|
||
vbo = ctx.buffer(vertices)
|
||
vao = ctx.vertex_array(program, vbo, 'in_position', index_buffer = ibo)
|
||
fbo = ctx.simple_framebuffer(res)
|
||
fbo.use()
|
||
fbo.clear(0.0, 0.0, 0.0, 0.0)
|
||
vao.render(moderngl.TRIANGLES)
|
||
return Image.frombytes('RGBA', fbo.size, fbo.read(components=4), 'raw', 'RGBA', 0, -1)
|
||
|