Python
OpenGL
Blender
BGL

[Blender] BGL(OpenGL)でオフスクリーンで描いた図形を画像として出力する

gpu モジュールの gpu.offscreen を通すことでオフスクリーンでのBGL(OpenGL)での描画結果を利用できるようです。1
以下のコードではオフスクリーンでBGLを走らせた後、それの結果をBlenderの画像スロットに保存しています:

import bpy
import bgl
import gpu

def main():
    width = 256
    height = 256

    gos = gpu.offscreen.new(width,height)
    gos.bind(True)
    try:
        bgl.glMatrixMode(bgl.GL_PROJECTION)
        bgl.glLoadIdentity()

        bgl.glBegin(bgl.GL_QUADS)
        bgl.glColor4f( 0,0,1,1 )
        for p in [(0,0), (.5,0), (.5,.5), (0,.5)]:
            bgl.glVertex2f(*p)
        bgl.glEnd()

        bgl.glBegin(bgl.GL_QUADS)
        bgl.glColor4f( 1,0,0,1 )
        for p in [(0,0), (-1,0), (-1,-1), (0,-1)]:
            bgl.glVertex2f(*p)
        bgl.glEnd()

        buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
        x,y = 0,0
        bgl.glReadPixels(x, y, width, height , bgl.GL_RGBA, bgl.GL_FLOAT, buffer)

        out = prepare_blimage(width, height)
        out.pixels = buffer[:]
    finally:
        gos.unbind(True)

def prepare_blimage(width, height, name='output'):
    if name in bpy.data.images:
        img = bpy.data.images[name]
        if img.size[:] != (width,height):
            img.scale(width,height)
    else:
        img = bpy.data.images.new(name, width, height)
    return img


main()

a.jpg

上記のコード中ではBGL上での-1~1の範囲が画像での0~width,heightの範囲に対応しています。

また参考先のページ1では .draw_view3d() メソッドを利用してビューポートの内容をオフスクリーンレンダリングする例も紹介されています。


参考


  1. GPU Off-Screen Buffer (gpu.offscreen) — Blender 2.79.0 855d2955c49 - API documentation
    https://docs.blender.org/api/2.79/gpu.offscreen.html