pyimguiではOpenGLのコンテキストが喧嘩して諦めた。DearPyGuiではOpenGLを使っていない記事を発見。もしかしたら、OpenGLが使えるのではで試して成功。
まあ、説明がどうこうではないのでサンプルだけ。
import dearpygui.dearpygui as dpg
from OpenGL.GL import *
from OpenGL.WGL import *
from ctypes import *
import numpy as np
# OpenGL Context init
xsc, ysc =windll.user32.GetSystemMetrics(0),windll.user32.GetSystemMetrics(1)
hwnd = windll.user32.CreateWindowExA(0,0xC018,0,0,0,0,xsc,ysc,0,0,0,0)
hdc = windll.user32.GetDC(hwnd)
pfd = PIXELFORMATDESCRIPTOR()
SetPixelFormat(hdc, ChoosePixelFormat(hdc, pfd), pfd)
wglc = wglCreateContext(hdc)
wglMakeCurrent(hdc, wglc)
# OpenGL init
program = glCreateProgram()
shader = glCreateShader(GL_FRAGMENT_SHADER)
glsl = '''
#version 300 es
precision highp float;
out vec4 fragColor;
uniform vec2 iResolution;
uniform float iTime;
void mainImage(out vec4 fragColor, in vec2 fragCoord);
void main() {
mainImage(fragColor,gl_FragCoord.xy);
}
// shadertoy code
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
fragColor = vec4(col,1.0);
}
'''
glShaderSource(shader, glsl)
glCompileShader(shader)
if glGetShaderiv(shader, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(shader).decode())
glAttachShader(program, shader)
glLinkProgram(program)
glUseProgram(program)
glViewport(0, 0, 200, 200)
dpg.create_context()
dpg.create_viewport(title='Shader Window Test', width=500, height=500)
dpg.setup_dearpygui()
dpg.show_viewport()
with dpg.texture_registry(show=False):
dpg.add_raw_texture(width=200, height=200, default_value=np.zeros(200*200*4), tag="shader_texture")
with dpg.window(label="shader"):
dpg.add_image("shader_texture")
while dpg.is_dearpygui_running():
glUniform2f(glGetUniformLocation(program, "iResolution"), 200, 200)
glUniform1f(glGetUniformLocation(program, "iTime"), dpg.get_total_time())
glRects(1, 1, -1, -1)
pixels = glReadPixels(0, 0, 200, 200, GL_RGBA, GL_UNSIGNED_BYTE)
pixels = np.frombuffer(pixels,dtype=np.uint8).astype(np.float32)/255.
dpg.set_value("shader_texture", pixels)
dpg.render_dearpygui_frame()
dpg.destroy_context()
wglMakeCurrent(0, 0)
wglDeleteContext(wglc)
これはshaderだけの描画だけど、OpenGLが使えるので、後はどうにでも展開できる。pyopenglはCのOpenGLのライブラリーのラッパーなので、作法はCと同じ。速さはCで書くには負けると思うが、気楽に書けるのが良い。