OpenGL ES 2.0 (今のところ iOS) を使用して 2D ゲーム エンジンを作成しようとしています。Objective C でアプリケーション レイヤーを作成し、C++ で別の自己完結型 RendererGLES20 を作成しました。レンダラーの外部で GL 固有の呼び出しは行われません。それは完全に機能しています。
しかし、シェーダーを使用する場合、いくつかの設計上の問題があります。各シェーダーには、メインの描画呼び出し (この場合は glDrawArrays) の直前に設定する必要がある独自の属性とユニフォームがあります。たとえば、ジオメトリを描画するには、次のようにします。
void RendererGLES20::render(Model * model)
{
// Set a bunch of uniforms
glUniformMatrix4fv(.......);
// Enable specific attributes, can be many
glEnableVertexAttribArray(......);
// Set a bunch of vertex attribute pointers:
glVertexAttribPointer(positionSlot, 2, GL_FLOAT, GL_FALSE, stride, m->pCoords);
// Now actually Draw the geometry
glDrawArrays(GL_TRIANGLES, 0, m->vertexCount);
// After drawing, disable any vertex attributes:
glDisableVertexAttribArray(.......);
}
ご覧のとおり、このコードは非常に厳格です。波及効果などの別のシェーダーを使用する場合、追加のユニフォーム、頂点属性などを渡す必要があります。つまり、新しいシェーダーを組み込むためだけに RendererGLES20 レンダリング ソース コードを変更する必要があります。
シェーダー オブジェクトを完全に汎用にする方法はありますか? たとえば、シェーダー オブジェクトを変更したいだけで、ゲーム ソースの再コンパイルを気にしない場合はどうすればよいでしょうか? レンダラーをユニフォームや属性などにとらわれないようにする方法はありますか? ユニフォームにデータを渡す必要がありますが、それを行うのに最適な場所はどこですか? モデルクラス?モデル クラスはシェーダー固有のユニフォームと属性を認識していますか?
以下は、Actor クラスを示しています。
class Actor : public ISceneNode
{
ModelController * model;
AIController * AI;
};
モデル コントローラ クラス: class ModelController { class IShader * shader; int textureId; vec4 色合い; 浮動小数点アルファ; struct Vertex * vertexArray; };
シェーダー クラスには、シェーダー オブジェクト、サブルーチンのコンパイルとリンクなどが含まれています。
Game Logic クラスでは、実際にオブジェクトをレンダリングしています。
void GameLogic::update(float dt)
{
IRenderer * renderer = g_application->GetRenderer();
Actor * a = GetActor(id);
renderer->render(a->model);
}
Actor は ISceneNode を拡張しますが、まだ SceneGraph の実装を開始していないことに注意してください。この問題が解決したらすぐに実行します。
これを改善する方法はありますか?関連するデザインパターンなどは?