FrameBuffer




画面をキャプチャする

glReadPixels() を利用して画面をClientMemoryにコピーする
void App::draw() { // 何か FrameBuffer に描く draw(); // 適当なイベントで実行する if ( mouseEvent ) { const int sz = 800 * 600 * 4; byte[] buf = new byte[ sz ]; // サイズ 800, 600 の画面を buf へコピーする glReadPixels( 0, 0, 800, 600, GL_RGBA, GL_UNSIGNED_BYTE, buf ); // Fileに出力する FILE *fp = fopen( "capture.raw", "wb" ); fwrite( buf, sz, 1, fp ); fclose(fp); delete[] buf; } }



glReadPixels

SYNTAX void glReadPixels( int x, int y //読み取る領域の左下隅の Window空間の x, y座標 unsigned int width, height //読み取る領域の幅, 高さ GL_BGRA, //取得したい色情報の形式() GL_UNSIGNED_BYTE, //読み取ったデータを保存する配列の型 void *buf //データを保存する配列へのポインタ ); DESC Framebuffer の内容をクライアントメモリへ Copy する WARNING この処理は、かなりの負荷がかかる Default は BackBuffer から得る この Command は 終了するまで制御を返さない そして GL の Pipeline をすべて Flush する
App::init() { //画像(読み取る領域)のピクセル数 int nr = w * h; // 1 Pixel 要素数 ( RGB 3 RGBA 4 ) int format = 4; //rgba // バッファから読み取ったデータを格納する配列 byte[] buf = new byte[nr * format]; //読み取るバッファを指定 //バックバッファを読み取る //フロントバッファを読み取りたい GL_FRONT を指定 glReadBuffer( GL_BACK ); // ClientMemory への Pack ( 詰め込み )方法の指定 // Defalut ( GL_RGBA, GL_UNSIGNED_BYTE )は 密にセットする // glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // FrameBuffer image を使う Texture Object glGenTextures( 1, &gId ); glBindTexture( GL_TEXTURE_2D, gId ); } App::draw() { // Scene を描画 drawScene(); // FrameBuffer から Pixel Data 取得 glReadPixels( 500, //読み取る領域の左下隅のx座標 500, //読み取る領域の左下隅のy座標 SW, //読み取る領域の幅 SH, //読み取る領域の高さ GL_RGBA, //取得したい色情報の形式() GL_UNSIGNED_BYTE, //読み取ったデータを保存する配列の型 gBuf //読み取ったデータを保存する配列 ); // Image の更新 glBindTexture( GL_TEXTURE_2D, gId ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, SW, SH, 0, GL_RGBA, GL_UNSIGNED_BYTE, gBuf ); // 一度かいた絵を利用して何かする draw(); }



glReadBuffer

SYNTAX void glReadBuffer( GLenum target ) DESC 読み取るバッファを指定 glReadPixels() などに影響する
// 最初の 1 回目の描画は FrontBuffer には未初期化の画像があることがわかる glReadPixels( GL_FRONT );



glPixelStorei

SYNTAX void glPixelStorei(GLenum pname, GLint val) DESC set pixel storage modes Main Memory と OpenGL 側の Memory でデータを転送するときに Data がどのように配置( Alignment )されているか教える 1, 2, 4, 8 を指定できる 初期値は 4 この数が 大きいほど 効率的に Data を転送できる DEFAULT 4 POINT unpack とは Application が GL に Pixel Data を送り出す時の指定方法 "store" 命令 と考えれば OK GL_UNPACK_ALIGNMENT Specifies the alignment requirements for the start of each pixel row in memory. The allowable values are 1 (byte-alignment), 2 (rows aligned to even-numbered bytes), 4 (word-alignment), 8 (rows start on double-word boundaries). The initial value is 4. // ClientMemory から Read する方法を指定する // だから glTexImage2D() にとってとても重要
// バッファの読み取り方を指定する // Alignment を指定する // glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); WARNING // 1 Pixel 3 byte の raw format を利用するときは必須 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); void *img = readRawTexture( "./test.raw" );



glCopyPixels

SYNTAX glCopyPixels( s32 x, y, // 読み取り位置 u32 w, h, // 大きさ s32 type // Copy する Buffer の指定 ( GL_COLOR | GL_DEPTH | GL_STENCIL ) ); DESC 指定した Buffer を RasterPos の位置に Copy


glCopyTexImage2D

SYNTAX void glCopyTexImage2D( s32 tgt, s32 lvl, s32 ifmt, // Copy すべき対象を指定する // GL_LUMINANCE : 輝度値のみ // TextureObject にも DepthBuffer がある s32 x,y,w,h, // Copy する FrameBuffer の矩形 // FrameBuffer( ReadBuffer ) の 左下.w, h は, FrameBuffer の左下からの サイズ. // 小さい値をセットすれば当然きれる ( 観測すみ. ) s32 border ); DESC FrameBuffer( BackBuffer )から 画像data を TextureObject に Copy する MultiPath には必須の API TIP parameter は glTexImage2D() と同じ pixel data の転送元が異なるだけ ARG3 : ReadBuffer からどの値をとるよーという宣言. -> BackBuffer は, RGB + DEPTH だったから別々にとることも可能. -> Texture も Buffer だから どんな内部構成( ifmt )にするかの指定が可能 WARNING w, h は 2冪.(VER:2.0 ) 画面全体を copy するならば, 2 冪でないとだめ ?
// Depth 値もとれる glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 0, 0, vpW, vpH, 0 );
// Copy 先の Texture Object を選択 glBindTexture( GL_TEXTURE_2D, id ); if ( 0 ) { glReadPixels( 500, //読み取る領域の左下隅のx座標 500, //読み取る領域の左下隅のy座標 SW, //読み取る領域の幅 SH, //読み取る領域の高さ GL_RGBA, //取得したい色情報の形式() GL_UNSIGNED_BYTE, //読み取ったデータを保存する配列の型 gBuf //読み取ったデータを保存する配列 ); // Image の更新 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, SW, SH, 0, GL_RGBA, GL_UNSIGNED_BYTE, gBuf ); } else { // こちらの方が高速 glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 500, 500, SW, SH, 0 ); }



glCopyTexSubImage2D

SYNTAX glCopyTexSubImage2D( GLenum target, GLint level, GLint x, y, // Copy 先の Texture の位置 GLint x, y, // Copy 元の FrameBuffer の位置と大きさ GLsizei w, h ) WARNING CubeMap には 裏側から利用するため Texture を反転する