最終更新:
mikk_ni3_92 2008年09月12日(金) 16:48:27履歴
現在地 >> メニュー >> 基本編10 >> PixelBufferObject
関連:VertexBufferObject、FrameBufferObject
「ピクセルデータ」を貯めておく「バッファオブジェクト」が「PixelBufferObject(PBO)」を呼ばれる。
「PBO」は「VertexBufferObject」のAPIを使っているが、そこに「PBO」用の「トークン」を指定する。
これによって、「メモリマネージャ(OpenGLのDriver)」が「shared memory」か「ビデオメモリ」がよいか判断する。
また、「PBO」がどのように使われるかも指定する。
![](https://image01.seesaawiki.jp/m/2/mikk_ni3_92/c7519c889e02e0a5.jpg)
▲PBOにおける「PACK」「UNPACK」の概念図
これは、OpenGLの関数でいうと
以下はglReadPixelsを用いた時の動作例。
[例1]
[例2]
PBOはVBOのAPIを使っている。
違いは「GL_PIXEL_PACK_BUFFER_ARB」と「GL_PIXEL_UNPACK_BUFFER_ARB」を使う点である。
これは、
※このトークンを基に動作しようとするが、最終的にはOpenGLのドライバが判断する。
これはVBOと同じ。
[例]
GL_STREAM_DRAW_ARB:動的なテクスチャのアップロードなどに使う。
GL_STREAM_READ_ARB:非同期のフレームバッファなどで使う。
この関数は成功するとバッファオブジェクトへのポインタをわたす。失敗するとNULL。
第1引数
第2引数
ここで、マッピングされたバッファをどうするか決める。
※メモ
もしGPUがバッファオブジェクトに関して動作していると、GPUが処理を終えるまで、この関数はreturnをしない。
この待機状態を避けるには、まず、glBufferDataARB()をNULLポインタでよぶ。それからglMapBufferARB()関数をよぶ。
すると、OpenGLは古いバッファをすてて、新しくメモリを確保する。
この関数を使って、マッピングされたバッファを解放する。
[例]
関連:VertexBufferObject、FrameBufferObject
「ピクセルデータ」を貯めておく「バッファオブジェクト」が「PixelBufferObject(PBO)」を呼ばれる。
「PBO」は「VertexBufferObject」のAPIを使っているが、そこに「PBO」用の「トークン」を指定する。
これによって、「メモリマネージャ(OpenGLのDriver)」が「shared memory」か「ビデオメモリ」がよいか判断する。
また、「PBO」がどのように使われるかも指定する。
- GL_PIXEL_PACK_BUFFER_ARB → 「ピクセルデータ」を「PBO」に転送する時に使う
- GL_PIXEL_UNPACK_BUFFER_ARB → 「PBO」から「ピクセルデータ」に転送する時に使う。
![](https://image01.seesaawiki.jp/m/2/mikk_ni3_92/c7519c889e02e0a5.jpg)
▲PBOにおける「PACK」「UNPACK」の概念図
これは、OpenGLの関数でいうと
- 「glReadPixels()」や「glGetTexImage()」 → 「PACK」の処理
- 「glDrawPixels()」や「glTexImage2D()」、「glTexSubImage2D()」 → 「UNPACK」の処理
以下はglReadPixelsを用いた時の動作例。
[例1]
- 「GL_PIXEL_PACK_BUFFER_ARB」 を指定
- glReadPixels()を実行する
[例2]
- 「GL_PIXEL_UNPACK_BUFFER_ARB」を指定
- glReadPixels()を実行する
PBOはVBOのAPIを使っている。
違いは「GL_PIXEL_PACK_BUFFER_ARB」と「GL_PIXEL_UNPACK_BUFFER_ARB」を使う点である。
これは、
- GL_PIXEL_PACK_BUFFER_ARB:ピクセルデータをOpenGLからアプリケーションに転送する時
- GL_PIXEL_UNPACK_BUFFER_ARB:ピクセルデータをアプリケーションからOpenGLに転送する時
※このトークンを基に動作しようとするが、最終的にはOpenGLのドライバが判断する。
- 作成
- バインド
- データのコピー
これはVBOと同じ。
[例]
GLuint PboId[1]; const int DataSize = ImageWidth * ImageHeight * nChannel; //データサイズ ... ... glGenBuffersARB(1, PboId); //PBOを1つ作成 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, PboId[0]); //バインド glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, DataSize, 0, GL_STREAM_DRAW_ARB); //コピー
GL_STREAM_DRAW_ARB:動的なテクスチャのアップロードなどに使う。
GL_STREAM_READ_ARB:非同期のフレームバッファなどで使う。
この関数は成功するとバッファオブジェクトへのポインタをわたす。失敗するとNULL。
void* glMapBufferARB(GLenum target, GLenum access)
第1引数
- GL_PIXEL_PACK_BUFFER_ARB
- GL_PIXEL_UNPACK_BUFFER_ARB
第2引数
ここで、マッピングされたバッファをどうするか決める。
- GL_READ_ONLY_ARB:読み込むだけ
- GL_WRITE_ONLY_ARB:書き込むだけ
- GL_READ_WRITE_ARB:読み書きの両方
※メモ
もしGPUがバッファオブジェクトに関して動作していると、GPUが処理を終えるまで、この関数はreturnをしない。
この待機状態を避けるには、まず、glBufferDataARB()をNULLポインタでよぶ。それからglMapBufferARB()関数をよぶ。
すると、OpenGLは古いバッファをすてて、新しくメモリを確保する。
この関数を使って、マッピングされたバッファを解放する。
[例]
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,DataSize, 0, GL_STREAM_DRAW_ARB); unsigned char *color = (unsigned char*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); if(color) { //--- colorに対し何らかの書き込み ----// glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); //解放 }