スポンサーサイト

--年--月--日 --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

OpenGL でのレンダリングターゲットの変更(テクスチャに描画)

2005年10月25日 14:19

今日もプログラムの話(・∀・)

OpenGL について書かれているHPはいっぱいあるんだけど、それの拡張命令(ARB や EXTってつくやつ)については
全然説明しているHPがない。
ましてや日本語のHPだとまったくない!
ってことで、ちょっとだけやっぱりメモ帳代わりにブログに残しておきますw

最近のGPUでは浮動小数点のレンダリングバッファを使用できるのが当たり前になってきました。
これがあるとレンダリングレンジの幅がグンっと広がるのでHDRをした時きれいに表現できるわけですね。
HDRではパフォーマンスと人間の可視領域の関係から HALF(16ビットの浮動小数点) がよく使われます。

DirectX では普通に使えるんだけど、OpenGL では日本語のリファレンスにはのってなかったりするので記載しておきます。
んで、使い方はっていうと、、、

glTexImage2D でテクスチャを設定するときに使用する引数が EXT や ARB などで拡張されています。
これを使用することで浮動小数点バッファを作ることができるんですね~。

ってことで、以下に glTexImage2D で使用可能と思われる intternalfomat, format, type を列挙しますね。

  internalformat
    GL_RGBA
    GL_RGBA4
    GL_RGB5_A1
    GL_RGBA8
    GL_RGBA16
    GL_RGB10
    GL_RGB10_A2
    GL_RGBA16F_ARB
    GL_RGBA32F_ARB
    GL_RGB
    GL_RGB4
    GL_RGB5
    GL_RGB8
    GL_RGB16
    GL_RGB16F_ARB
    GL_RGB32F_ARB
    GL_ALPHA
    GL_ALPHA8
    GL_ALPHA16
    GL_ALPHA16F_ARB,
    GL_ALPHA32F_ARB,
    GL_INTENSITY
    GL_INTENSITY8
    GL_INTENSITY16
    GL_INTENSITY16F_ARB,
    GL_INTENSITY32F_ARB,
    GL_LUMINANCE
    GL_LUMINANCE8
    GL_LUMINANCE16
    GL_LUMINANCE16F_ARB
    GL_LUMINANCE32F_ARB
    GL_LUMINANCE_ALPHA
    GL_LUMINANCE8_ALPHA8
    GL_LUMINANCE16_ALPHA16
    GL_LUMINANCE_ALPHA16F_ARB
    GL_LUMINANCE_ALPHA32F_ARB,
    GL_DEPTH_COMPONENT
    GL_DEPTH_COMPONENT16
    GL_DEPTH_COMPONENT24
    GL_DEPTH_COMPONENT32,


  format
    GL_RGB
    GL_BGR
    GL_RGBA
    GL_BGRA
    GL_ABGR
    GL_ARGB
    GL_RED
    GL_GREEN
    GL_BLUE
    GL_ALPHA
    GL_LUMINANCE
    GL_LUMINANCE_ALPHA
    GL_DEPTH_COMPONENT


  type
    GL_BYTE
    GL_UNSIGNED_BYTE
    GL_SHORT
    GL_UNSIGNED_SHORT
    GL_INT
    GL_UNSIGNED_INT
    GL_HALF_FLOAT_ARB
    GL_FLOAT
    GL_2_BYTES,
    GL_3_BYTES,
    GL_4_BYTES,
    GL_DOUBLE,
    GL_UNSINGED_BYTE_3_3_2
    GL_UNSINGED_BYTE_2_3_3_REV
    GL_UNSIGNED_SHORT_4_4_4_4
    GL_UNSIGNED_SHORT_4_4_4_4_REV
    GL_UNSIGNED_SHORT_5_5_5_1
    GL_UNSIGNED_SHORT_1_5_5_5_REV
    GL_UNSIGNED_SHORT_5_6_5
    GL_UNSIGNED_SHORT_5_6_5_REV
    GL_UNSIGNED_INT_8_8_8_8
    GL_UNSIGNED_INT_8_8_8_8_REV
    GL_UNSIGNED_INT_10_10_10_2
    GL_UNSIGNED_INT_2_10_10_10_REV
    GL_UNSINGED_INT_24_8
    GL_UNSINGED_INT_8_24_REV


ざっと上げただけでこれぐらい。
まだまだ拡張されるかもしれないのでもっともっと増えるかもしれませんが、
とりあえず double のテクスチャバッファまで用意できるので当分の間これで充分な気がします。

それで、肝心の自分で用意したバッファに描画する方法ですが、、、
OpenGL で 自分で用意したレンダリングバッファ(レンダリングテクスチャ)に描画する方法はまだドラフトしてる最中(もう終わったのかな?)だったりします。
そんなわけで、これまた拡張関数を使って行います。
これまた日本語で書いてあるHPが見つからなかったのでここに乗っけておきますね。

Googleとかから「OpenGL」「Render」「Texture」とかのキーワードで検索してきた人が参考にしてくれたら幸いです。




PFNGLGENFRAMEBUFFERSEXTPROC      glGenFramebuffersEXT;
PFNGLBINDFRAMEBUFFEREXTPROC      glBindFramebufferEXT;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC    glFramebufferTexture2DEXT;
PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;

// 関数ポインタを取得
void InitOpenGLExtension()
{
  glGenFramebuffersEXT    = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress( "glGenFramebuffersEXT" );
  glBindFramebufferEXT    = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress( "glBindFramebufferEXT" );
  glFramebufferTexture2DEXT  = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress( "glFramebufferTexture2DEXT" );
  glDeleteFramebuffersEXT   = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress( "glDeleteFramebuffersEXT" );
}


// レンダリングバッファを作成
void CreateRenderingBuffer( OUT GLuint *pFrame, OUT GLuint *pColor, OUT GLuint *pDepth, IN int width, IN int height )
{
  // フレームバッファオブジェクト、デプスとカラー用のテクスチャを作成
  glGenFramebuffersEXT( 1, pFrame );
  glGenTextures( 1, pColor );
  glGenTextures( 1, pDepth );

  // とりあえず、作るカラーバッファは HALF 型
  glBindTexture( GL_TEXTURE_2D, *pColor );
  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, width, height, 0, GL_RGBA, GL_HALF_FLOAT_ARB, NULL );

  // 深度バッファも作成
  glBindTexture( GL_TEXTURE_2D, *pDepth );
  glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL );

  // テクスチャをフレームバッファオブジェクトにバインド
  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, *pFrame );
  glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, *pColor, 0 );
  glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, *pDepth, 0 );

  // デフォルトのレンダーターゲットに戻す
  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
}




InitOpenGLExtension 関数で初期化して CreateRenderingBuffer 関数でレンダリングバッファを作成するわけですね。
後は、出来上がったレンダリングバッファに描画するんですけど、描画の仕方はっていうと、、、、

void Draw( IN GLuint frame )
{
  // バッファを変更
  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, frame );
  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
  glViewport( 0, 0, render_width, render_height );

  // オブジェクトを描画
  ....


  // デフォルトのレンダーターゲットに戻し、ディスプレイに描画
  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
  glViewport( 0, 0, screen_width, screen_height );


  // ポスト処理やらなにやらを行う。
  ....
}


こんな感じになります。
frame は CreateRenderingBuffer 関数で作成したフレームバッファオブジェクトのことです。
必ず最後にデフォルトのレンダーターゲットに戻して、それに描画しないとだめです。
じゃないと表示されません('A`)

また、最後にフレームバッファオブジェクトとテクスチャオブジェクトを削除しましょう。
フレームバッファオブジェクトの削除は glDeleteFramebuffersEXT 関数を使用します。

サンプルは、、、後日UPしますw
スポンサーサイト


コメント

    コメントの投稿

    (コメント編集・削除に必要)
    (管理者にだけ表示を許可する)

    トラックバック

    この記事のトラックバックURL
    http://angra.blog31.fc2.com/tb.php/11-c1d44c7a
    この記事へのトラックバック


    最近の記事


    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。