シェーダープログラム管理クラス¶
GLSL プログラムオブジェクトとシェーダーオブジェクトの生成と破棄の管理方法はワンパターンなので、この機能をカプセル化した管理クラス ProgramManager
を作成しておき、アプリケーションクラス AppBase
にオブジェクトを保持させて用いるようにする。
Warning
私の環境でプログラムが適切なグラフィックドライバーを取得できない不具合が発生しており、関数 glCreateShader
が None
になるせいで本稿のクラスは動作しない。
クラス ProgramManager
¶
次に挙げるようなコードを書いておく。部分的には PyOpenGL の某モジュールにも同様のコード片がある。
#!/usr/bin/env python
"""program_manager.py: Define class ProgramManager.
"""
import OpenGL.GL as GL
class ProgramManager(object):
"""OpenGL shader program manager.
This class managers a program object and its shader objects.
"""
def __init__(self):
"""Initialize an instance of class ProgramManager."""
self.program_id = 0
self.shader_sources = None
self.shader_ids = {}
def setup(self, shader_sources):
"""Setup shaders."""
if not shader_sources:
return
shader_ids = {}
for shader_type, source in shader_sources.items():
shader = GL.glCreateShader(shader_type)
GL.glShaderSource(shader, source)
GL.glCompileShader(shader)
if GL.glGetShaderiv(shader, GL.GL_COMPILE_STATUS) != GL.GL_TRUE:
raise RuntimeError(GL.glGetShaderInfoLog(shader).decode())
shader_ids[shader_type] = shader
self.shader_sources = shader_sources
self.shader_ids = shader_ids
self.program_id = GL.glCreateProgram()
for shader in shader_ids.values():
GL.glAttachShader(self.program_id, shader)
GL.glLinkProgram(self.program_id)
if GL.glGetProgramiv(self.program_id, GL.GL_LINK_STATUS) != GL.GL_TRUE:
raise RuntimeError(GL.glGetProgramInfoLog(self.program_id).decode())
GL.glUseProgram(self.program_id)
def cleanup(self):
"""Clean up shaders and program."""
if not self.shader_sources:
return
GL.glUseProgram(0)
for shader in self.shader_ids.values():
GL.glDetachShader(self.program_id, shader)
GL.glDeleteShader(shader)
GL.glDeleteProgram(self.program_id)
メンバーデータの説明¶
program_id
関数
glCreateProgram
の戻り値をここに保持する。アプリケーションは、GLSL 構成要素にアクセスするときにはこの値を参照することになる。shader_sources
これは辞書オブジェクトで、そのキーは関数
glCreateShader
の引数であり、値はその戻り値と一緒に関数glShaderSource
に与える引数(プログラムコード)のペアを想定している。shader_ids
これも辞書オブジェクトで、そのキーは先程の辞書と同じものであり、値は先程の関数
glCreateShader
の戻り値(シェーダープログラム識別子)である。
メソッドの説明¶
アプリケーションはメソッド setup
と cleanup
をその初期化処理と後始末処理にて呼び出す。