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;
};
モデルコントローラークラス:クラスModelController {クラスIShader *シェーダー; int textureId; vec4ティント。浮動小数点アルファ; struct Vertex * vertexArray; };
Shaderクラスには、シェーダーオブジェクト、サブルーチンのコンパイルとリンクなどが含まれます。
Game Logicクラスでは、実際にオブジェクトをレンダリングしています。
void GameLogic::update(float dt)
{
IRenderer * renderer = g_application->GetRenderer();
Actor * a = GetActor(id);
renderer->render(a->model);
}
ActorはISceneNodeを拡張していますが、まだSceneGraphの実装を開始していないことに注意してください。この問題を解決したらすぐにそれを行います。
これを改善する方法はありますか?関連デザインパターンなど?
質問を読んでいただきありがとうございます。