OpenGLでの描画内容の画像化と保存
OpenGLで描画した情報をピクセル単位で取得し、画像化および保存したかったので、調べてみました。
OpenGLのglReadBufferとglReadPixels関数を使うようです。
一つのまとまった小さなプログラムコードは、探した限りでは無かったので書いてみました。
OpenCVを画像の保存に使っていますが、取得したピクセル情報は変数dataBufferに入っているので、
あとは自分の好きなように格納できると思います。
void saveImage( const unsigned int imageWidth, const unsigned int imageHeight ) { const unsigned int channnelNum = 3; // RGBなら3, RGBAなら4 void* dataBuffer = NULL; dataBuffer = ( GLubyte* )malloc( imageWidth * imageheight * channelNum ); // 読み取るOpneGLのバッファを指定 GL_FRONT:フロントバッファ GL_BACK:バックバッファ glReadBuffer( GL_BACK ); // OpenGLで画面に描画されている内容をバッファに格納 glReadPixels( 0, //読み取る領域の左下隅のx座標 0, //読み取る領域の左下隅のy座標 //0 or getCurrentWidth() - 1 imageWidth, //読み取る領域の幅 imageHeight, //読み取る領域の高さ GL_BGR, //it means GL_BGR, //取得したい色情報の形式 GL_UNSIGNED_BYTE, //読み取ったデータを保存する配列の型 dataBuffer //ビットマップのピクセルデータ(実際にはバイト配列)へのポインタ ); GLubyte* p = static_cast<GLubyte*>( dataBuffer ); std::string fname = "outputImage.jpg"; IplImage* outImage = cvCreateImage( cvSize( imageWidth, imageHeight ), IPL_DEPTH_8U, 3 ); for ( unsigned int j = 0; j < imageHeight; ++ j ) { for ( unsigned int i = 0; i < imageWidth; ++i ) { outImage->imageData[ ( imageHeight - j - 1 ) * outImage->widthStep + i * 3 + 0 ] = *p; outImage->imageData[ ( imageHeight - j - 1 ) * outImage->widthStep + i * 3 + 1 ] = *( p + 1 ); outImage->imageData[ ( imageHeight - j - 1 ) * outImage->widthStep + i * 3 + 2 ] = *( p + 2 ); p += 3; } } cvSaveImage( fname.c_str(), outImage ); }
廣瀬