シェーダープログラム管理クラス

GLSL プログラムオブジェクトとシェーダーオブジェクトの生成と破棄の管理方法はワンパターンなので、この機能をカプセル化した管理クラス ProgramManager を作成しておき、アプリケーションクラス AppBase にオブジェクトを保持させて用いるようにする。

Warning

私の環境でプログラムが適切なグラフィックドライバーを取得できない不具合が発生しており、関数 glCreateShaderNone になるせいで本稿のクラスは動作しない。

クラス 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 の戻り値(シェーダープログラム識別子)である。

メソッドの説明

アプリケーションはメソッド setupcleanup をその初期化処理と後始末処理にて呼び出す。