OpenGLフィードバック

今日の学生クエストは、OpenGLの描画結果を加工したい、あるいは、フィードバックさせたい、でございました。例えば、以下はトーラス(+補助軸)が1個存在しているだけですが、描画結果に回転歪みをかけながらフィードバックさせているので、複雑な画像になっています。

opengl-feedback.jpg

2061:Maxオデッセイでは、p.839にマトリックスへレンダリングする方法を紹介しています。マトリックスになれば画像処理もフィードバックも簡単ですね。しかし、この場合はCPUによるソフトウェア・レンダリングになり、処理速度が落ちてしまいます。そこで、GPUによるハードウェア・レンダリングのまま処理を行いたいわけです。

解決策:jit.gl.renderへto_textureメッセージ、jit.gl.textureから描画結果を得る。

うむ〜なんのことやら分かりませんね。取り敢えず、パッチは以下の通りで、ダウンロードはこれopengl-feedbackpat.zipです。

opengl-feedback-pat_m.gif

ポイントはjit.gl.renderにbangを送ってレンダリングした画像を、to_textureメッセージでテクスチャーに転送していることです(bangbangの1番目)。どのテクスチャーかはusetextureで指定し、ここではtexという名前でloadmessを使って自動設定しています。

このテクスチャーは、texをnameアトリビュートで指定したjiit.gl.textureから出力され、jit.gl.imageunitで加工した後、jit.gl.videoplaneに貼付けて表示します(bangbangの3番目)。この画像は1フレーム前の画像として描画され、その上にjit.gl.gridshapeによって新しいトーラスを描きます(bangbangの2番目)。

ここでのテクチャーはJitter 1.6から新たに加わったもので、OpenGL(GPU)上の画像データと考えれば良いでしょう。テクチャーが流れるパッチコードは水色になります。

以上を繰り返すことによって、OpenGLでレンダリングされた画像を加工しつつ、フィードバックさせているのが、このパッチでの処理です。テクスチャーとして処理しているので、GPU上でデータの遣り取りが行われており、CPUへの負荷はほとんどかかっていないハズです。

ちなみに、jit.gl.imageunitを省略すれば、単純なフィードバックになります。また、jit.gl.videoplaneの位置、大きさ、回転、透明度などを変えることで、フィードバックの起こり方が変わります。また、jit.gl.videoplane自体も3次元物体なので、トーラスを交わらせるとトーラスの一部が切り取られます。これがイヤなら、jit.gl.videoplaneを十分遠くに置いて、ウィンドウに合うように大きくすれば良いと思います。あるいは、他の物体を十分手前に置くことでもいいです。

OpenGLフィードバック」への4件のフィードバック

  1. topcap

    jit.gl.videoplaneを利用したプロジェクタの台形補正について
    はじめまして。
    いつも参考にさせていただいております。

    jit.gl.textureとjit.gl.videoplaneの動作について質問なのですが、今回のように、jit.gl.renderがレンダリングする空間内にjit.gl.videoplaneを配置するのではなく、図のように別のjit.gl.render内にテクスチャを転送することはできないでしょうか?

    プロジェクタの台形補正をしようと試してみたのですが、どうにもテクスチャの転送がうまくいかず困っております。OpenGLにおける仕様の問題なのでしょうか。

    返信
  2. aka

    > 図のように別のjit.gl.render内にテクスチャを転送することはできないでしょうか?

    jit.gl.renderが2つあり、ドローイング・コテンテクストも2つある、ということですよね?

    もしそうなら、テクスチャーはjit.gl.renderが管理しており、異なるドローイング・コテンテクストでは使えないような気がします。(もう少し考えてみますが…)

    ただ、jit.gl.textureのアトリビュートにshareってのがあって、
    Flag to enable or disable sharing texture data across multiple OpenGL contexts (default = 1).
    ってことで、それじゃできるはずと思ってやってみたら、jit.gl.videoplaneには市松模様が描かれちゃいました。

    取り敢えずの打開策として、OpenGLレコーディングの記事のように、レンダリング結果をマトリックスに変換して、それをjit.gl.videoplaneに送ってはどうでしょうか?

    返信
  3. topcap

    すばやいレスポンスありがとうございます。就職活動で数日留守にしていましたので、お返事が遅くなってしまいました。申し訳ございません。

    > jit.gl.renderが2つあり、ドローイング・コテンテクストも2つある、ということですよね?

    その通りです。

    > ただ、jit.gl.textureのアトリビュートにshareってのがあって、

    shareアトリビュート試してみました。しかし同様に市松模様になってしまいました。後ほどWindows環境でも試してみる予定です。

    そのほか、単一のOpenGLコンテキスト内にレンダリング対象とjit.gl.videoplaneを離して配置し、カメラ位置を交互に切り替えて……などと考えたのですが、テクスチャデータをレンダリングする為にはドローイングコンテキストの描画も同時に行われてしまうので、うまくいきませんでした。

    マトリックスへのレンダリングを利用すれば、表示に問題はないのですが、速度面で制約を受けてしまうので今回利用する予定はありません。

    返信
  4. aka

    蛇足かもしれませんが、「マトリックスへのレンダリング」じゃなくって、「レンダリング結果のマトリックスへの変換」ですよ。変換時間は多少かかりますが、レンダリング自体はGPUで行われるので、それほど処理速度の低下はないハズなんですが…

    返信

topcap へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です