2011-06-27 8 views
4

現在、OpenGLでレンダリングされた3D世界のスナップショットをglReadPixelsを使用して様々なカメラ位置とさまざまな画像解像度で撮影しようとしています。私は、OpenGLウィンドウプログラムを実装しているGUIライブラリの2つの選択肢を持っています:Qtとfreeglutです。両方で数回実験した結果、QtはQGLWidgetのスナップショットの画像解像度をデスクトップサイズに制限しないことに気付きましたが、私はfreeglutで同じことをすることができませんでした。非常に大きな画像解像度のOpenGLウィンドウのスナップショットを取得

このスナップショット取得プログラムでQtを使用したいのですが、同じプログラムの別のモジュールで作業しているプロジェクトチームのメイトが新しいライブラリとIDE(Qt Creator)を習得する余裕がないため、 )。彼はVisual Studio 2008を使用しています。

私はデスクトップのサイズに制限されず、4000 x 2000ほどの大きさになる可能性のあるglutウィンドウを作成しますか?

答えて

4

QtがQGLWidgetのスナップショットのイメージ解像度をデスクトップサイズに制限しないことを実感しましたが、私はfreeglutでも同じことをすることができませんでした。

注意:デスクトップよりも大きなウィンドウを作成した場合、表示されていないピクセルはピクセル所有テストに合格しません。したがって、これらのピクセルの内容は、は未定義です。彼らはかもしれませんあなたが望むものが含まれていますが、そうでないかもしれません。

これは、ウィンドウがデスクトップの外にあるか、別のウィンドウで覆われているかに関係なく、表示されないピクセルにも当てはまります。

とにかく、デスクトップのサイズのウィンドウを作成しないでください。通常のウィンドウを作成し、大きな色と深さを含むframebuffer objectを作成する必要があります。renderbufferこれらのオフスクリーンバッファーにすべてのレンダリングを行います。次に、ウィンドウのサイズの制限について心配する必要はありません。

+0

私はX 2500の周りに3000にスピンボタンを使用して、サイズを調整し、QStackedWidget内部派生QGLWidgetを配置することにより、QtのでテストしてからglReadPixelsとQGLWidget :: RenderPixmap(両方を使用している)にそのQGLWidgetのスクリーンショットをキャプチャして保存します。 QGLWidgetはGUIアプリケーション上で部分的にしか見えませんが、保存されたスクリーンショットは完璧です。 Qtがピクセルオーナーシップテストをかなりうまく処理したように思えます:) 提案されたソリューションは本当に面白いです。 OpenGLについての私の知識はまだ基本的な基本的な固定パイプラインなので、もっと読む必要があると思います。 – ksming

+1

Qtはピクセルオーナーシップテストを「処理」しません。 OpenGL仕様で定義されており、Qtが動作するレベルではなく、Win32/X-Windows/graphics-driver/etcレベルで処理されます。それがあなたにとってうまくいけば、この特定の低レベルのウィンドウシステムでは、あなたは_lucky_を持っているからです。それは信頼されるべきではありません。 –

8

OpenGLで高解像度のレンダリングを行うのはちょっと難しいです。 1つの問題は、ピクセル所有テストが途中で行われることです。もう1つは、フレームバッファ(オブジェクト)の最大サイズです。最初の問題は、フレームバッファオブジェクトまたはPBufferを使用することで解決できます。

2つめのトリッキーが必要です.WとHが最大フレームバッファサイズを超えるサイズW×Hのイメージをレンダリングするとします。 GL_MAX_VIEWPORT_SIZE、GL_MAX_TEXTURE_SIZE、GL_MAX_RENDERBUFFER_SIZEのトークンのglGetIntegerは、これらの制限を示しています。だからあなたがしなければならないことは、ターゲット画像をそれらの限界よりも小さいタイルに分割し、それらのタイルをレンダリングし、次にそれらを再結合することです。 W_tとH_tがタイルサイズ、W_t := W/NH_t := H/Mであり、それに応じたサイズのPBufferまたはFramebufferオブジェクトがあるとします。その後、我々は2ループでこれらのタイルをレンダリングすることができます。

for m in 0 to M: for n in 0 to N: 
    render_tile(n, m) 

それでは、どのようrender_tile(n,m)が見えますか?

render_tile(n,m): 

どうやら私たちはどのような変更が投影されレンダよう

glViewport(0, 0, W_t, H_t) 

を全体のタイルを使用しているが。どういうわけか、投影面のタイルと一緒に投影をシフトしなければなりません。投影面は、「近い」面としても知られています。近く飛行機のエクステントは、right - lefttop - bottomているので、我々はサイズ(right - left)/N×(top - bottom)/Mのタイルに近い平面を分割しているので、それは我々がシフトステップサイズとして使用するために必要なものです:

shift_X = (right - left)/N 
    shift_Y = (top - bottom)/M 

    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    switch Projection: 
     case Ortho: 
      glOrtho(left + shift_X * n, left + shift_X * (n+1), 
         bottom + shift_Y * m, bottom + shift_Y * (n+1), 
         near, far) 
     case Perspective: 
      glFrustum(left + shift_X * n, left + shift_X * (n+1), 
         bottom + shift_Y * m, bottom + shift_Y * (n+1), 
         near, far) 

    render_scene() 

そして、ちょうどどの場合私たちは、透視用left, right, top, bottomを得る:

right = -0.5 * tan(fov) * near 
left = -right; 
top = aspect * right 
bottom = -top 
+0

非常に詳細な答えをありがとう。 FBOをさらに調べて、このスナップショット取得タスクを実行しているマシンのGL_MAX_RENDERBUFFER_SIZE_EXT値を超えているかどうかを確認します。おそらく、FBO-RenderBufferObjectメソッドしか必要ないでしょう。もう一度ありがとう! – ksming

関連する問題