3

2 つの SFML ウィンドウを作成し、OpenGL を使用して両方に描画するにはどうすればよいですか?

OpenGL で 2 つ以上の SFML ウィンドウを作成して使用する方法を疑問に思ったことがあるなら、ここに解決策があります。インターネット上でこれを行う方法に関する情報を見つけることができなかったので、ここにあります。これがいつか誰かの役に立てば幸いです。

余談ですが、これが便利な理由を知りたい場合があります。

システムのアニメーションを他の人に見せることができることは、物理学者にとって非常に便利なことです。なぜなら、何かを説明するのに役立つデモンストレーションをプログラムしたいことがよくあるからです。些細な例は、箱の中のガス粒子の挙動です。上のウィンドウでは、粒子が描画され、私たちの凝った物理計算のおかげで現実の世界と同じように動き回り、別のウィンドウでは、ボックス内の総エネルギーまたは平均粒子速度 (温度) を示すためにグラフが描画される場合があります。などなど。別の良い例は、太陽系のシミュレーションです。惑星に関するデータを 1 つのウィンドウに描画し、太陽系のビューを別のウィンドウに描画できます。

4

1 に答える 1

2

これを機能させるには、いくつかの手順が必要です。複数のウィンドウの微妙な違いは、描画する前に各ウィンドウのサイズを変更する必要があるという事実にあります。または、少なくともこれが最も簡単な方法です。1 つのウィンドウでは、ウィンドウが作成された後にのみサイズ変更し、サイズ変更または形状変更のたびに変更します。マトリックススタックからプッシュおよびポップすることにより、これを行うより良い方法があると主張するかもしれません。その場合は、コメントして他の回答を残してください。

最初に、2 つの sfml ウィンドウを宣言する必要がありますsf::Window window, window2;

次に、両方のサイズ変更メソッドを実装します。このようなことができます。

/// Window
glViewport(0, 0, window.GetWidth(), window.GetHeight());
// Set matrix mode back again
glMatrixMode(GL_PROJECTION);
// Reset matrix stack
glLoadIdentity();
// Set drawing surface properties - either Perspective or Orthographic
///gluPerspective(45.0, (double)w / (double)h, 1.0d, 100.0d);
glOrtho(-50.0d, 50.0d, -50.0d, 50.0d, -10.0d, 10.0d);
// Put matrix mode back
glMatrixMode(GL_MODELVIEW);

そして今、他の:

/// Window2, which can be different to window!
glViewport(0, 0, window.GetWidth(), window.GetHeight());
// Set matrix mode back again
glMatrixMode(GL_PROJECTION);
// Reset matrix stack
glLoadIdentity();
// Set drawing surface properties - either Perspective or Orthographic
///gluPerspective(45.0, (double)w / (double)h, 1.0d, 100.0d);
glOrtho(-50.0d, 50.0d, -50.0d, 50.0d, -10.0d, 10.0d);
// Put matrix mode back
glMatrixMode(GL_MODELVIEW);

これら 2 つのコード ブロックを 2 つの異なる関数に配置し、選択したカメラ クラスを実装することもできます。これは、さまざまな OpenGL 描画メソッドを使用して描画する前に、各ウィンドウのサイズ変更関数を呼び出す必要があるためです。

さて、楽しい部分です。描画する前に、描画先のウィンドウのサイズ変更メソッドを呼び出します。次に、呼び出す必要があるglMatrixMode(GL_MODELVIEW);場合 (念のため!)、glLoadIdentity();、およびglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);. 明らかに、画面をクリアしたくない場合は、マトリックス変換スタックをリセットしたくない場合は、glClear または glLoadIdentity を呼び出さないでください...

今、あなたの描画を行います:glBegin()そしてglEnd()、あなたがする必要がある他のすべてのこと.

最後に、どちらに描画していたかに応じて、window.Display()またはを呼び出します。window2.Display()上記の楽しい部分に戻り、他のウィンドウのサイズ変更メソッドを呼び出し、最初のウィンドウとまったく同じように、この 2 番目のウィンドウに対して必要なすべての操作を続けます。

複数のウィンドウで OpenGL SFML プログラミングをお楽しみください。多数のウィンドウをベクターまたはその他の派手なコンテナーに突っ込みたいと思うかもしれません。

[編集] 何らかの理由で sf::Windows はコピー不可です。つまり、deque や vector のようなコンテナーに push_back() することはできません。これはおそらく、あるウィンドウ クラスから別のウィンドウ クラスにすべてのビットをコピーしようとすると、OpenGL 固有のことが原因である可能性があります。(おそらく?) 代わりにsf::Window* = new sf::Window[number_of_windows]and でunsigned int number_of_windows = 2十分ですが、それほど良くはありません...

于 2012-12-28T15:31:34.310 に答える