2017-05-29 16 views
0

terisのゲームを開発する私は、通常のMVCパターンを使用すると、コードが混乱する可能性があり、OpenGLがGLEWの下でどのように動作しているかによって、ビルドするのがかなり難しくなるとの結論に達しました。代わりに、私はもう少し理にかなってObserverパターンにも依存し、このきちんと修正、思い付いた、少なくとも短期的には(画像は完全なクラスツリーを反映していない):
makeshift architectureこのデザインの欠陥を解決するには?

説明するために:
-everyをボックスがクラスである場合、EngineEntitiesのインスタンスを保持し、GameFigureのインスタンスを保持します。
- Figureは、Entityを継承します。
- Engineは、Gameを観測し、Gameは、オブザーバーによってFiguresと結合される。
それがどのように動作するかを

理想的には、私は、新しいスレッドで、図を作成します、Gameオブジェクトを作成し、ウィンドウを占めるようになる他のすべてと一緒にGLEWとGLFWを設定しますどのEngineをインスタンス化する必要があり、描画ループを開始するようにエンジンに通知し、そのFigureが設定されたらObserverを介してEngineへのオブジェクトポインタを渡します。
これはきれいに機能しますが、Entityを継承してすべての種類の図を追加できます。すべての座標の更新がGameを通過するため、数字が画面から消えず、おそらくすべての図にユニークなそれが必要ならば、シェーダ。図は、別のスレッドで呼び出され、ゲームが初期化され、
エンジンが初期化され、任意のOpenGLの機能にアクセスすることを求められたとき

atioglxx.dll: 0xC0000005: Access violation reading location 0x00000728. 

スロー:

それは実際にどのように動作します。
Engineですべてのサポート機能が起動されていることをFigureが知りません。そして、私はFigureで再びそれをすることはできません。 Viewで行う必要があるすべてのものをEngineに移動することはできますが、別のシェーダを設定することはできません。EngineのすべてのFigureに対してVAO(Vertex Array Objects)を構築する必要があります。
できるだけ変更を加えずに、エラーをなくすにはどうすればよいですか?

+0

これは興味深い問題であってもよいが、ここでオフトピックかもしれ。 – Walter

+0

@Walter、私はそれをgamedev.stackに置くことを考えましたが、建築上の問題をあまり扱っていないようです –

答えて

0

短い答えは、特定のコンテキストに対するすべてのOpenGL呼び出しが同じスレッド上にある必要があるということです。長い答えは


まず、Entities必要がGLの通話で自分自身を描くことができるように...道を進んでいます。あるスレッドの描画コードと別のスレッドの描画コードを混在させることはできません。OpenGLクライアントの状態は正しくありません。 (OpenGLを 'C'状態マシンと考える)。

第2に、エンティティの状態をフレームごとにバッファする必要があります。 Engineは、Gameスレッドで次のフレームを開始するときに描画呼び出しを送信したり、終了したりしない場合があります。したがって、すべてのフレームをEntity州に送信するには、いくつかの同期方法が必要です。これは、あなたのパイプラインを停止させたり、ブロックを引き起こしたりする可能性のある同期プリミティブ(mutexなど)を避けたいので、ややこしいことです。

Engineバックエンドへのドローコールの送信にダブルバッファーパイプラインを使用したDoom III source codeを読むことができます。そのトリックは、Doomがメインスレッドでほとんどすべてを行い、次にバックエンド(Engine)スレッドで描画呼び出しを実行するように分割し、Gameメインスレッドの次のフレームに描画状態(Entities)を送信することです。次に、Engineスレッドで終了し、バッファをスワップします。

メタルとVulkanのマルチスレッドを読む。これらは非常に似ています。

リソースはEngineにロードする必要があり、参照するために、あなたのエンティティのハンドルを戻した(シェーダ、テクスチャ、静的Geomety、など...)

関連する問題