■ 画面をキャプチャする
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(
int x, y, // 読み取り位置
unsigned int w, h, // 大きさ
int type // Copy する Buffer の指定 ( GL_COLOR | GL_DEPTH | GL_STENCIL )
);
DESC
指定した Buffer を RasterPos の位置に Copy
■ glCopyTexImage2D
SYNTAX
void glCopyTexImage2D(
int tgt,
int lvl,
int ifmt, // Copy すべき対象を指定する
// GL_LUMINANCE : 輝度値のみ
// TextureObject にも DepthBuffer がある
int x,y,w,h, // Copy する FrameBuffer の矩形
// FrameBuffer( ReadBuffer ) の 左下.w, h は, FrameBuffer の左下からの サイズ.
// 小さい値をセットすれば当然きれる ( 観測すみ. )
int 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 を反転する