キャプチャする

最終更新日31 Jul 2017 02:56

OpenGLのレンダリング結果をpngで保存したい。
普通にキャプチャソフトでとってもいいのだけど、
図形だけで背景は透明とかできないかなと思い、
プログラム内部からキャプチャ画像を生成する方法を調べた。
そのうち、自動的にgif画像とか作りたいな。

glReadPixels()でフレームバッファからプロセッサのメモリにピクセルデータを読み込む

普通に書くとこうなる。

glReadPixels(0,0,width,height,GL_RGBA,GL_UNSIGNED_BYTE,読み込み先のポインタ);

もしこの場合だと、読み込み先の配列のサイズは

width*height*4

バイトになる。4なのはRGBAだから。
ダブルバッファリングしている場合は、事前にフロントバッファとバックバッファのどちらを読み込むのか指定する必要がある

glReadBuffer(GL_FRONT);// フロントを読み込む様に設定する

せっかくパソコンのメモリに落とし込んだフレームバッファの内容けど、
今度はそれをどうやってpngにアウトプットするかが大事。
tgaで出力ならば、glfwで標準でありそう。
それからImageMagickでpngに変換してもいいかも?
libpngも試してみたけど、私のWindows環境ではどうもうまくいかなかった。

背景透過で画像保存するには

また、OpenGLで描いたところだけ保存したいなら,
ウィンドウ生成時にちゃんとアルファチャンネルを使うことを明示する必要がある

glfwOpenWindow(300,300,0,0,0,8/*alpha*/,0,0, GLFW_WINDOW );

参照:glfwOpenWindow()
using namespace System::Drawing;
void capture(GLFWwindow *window) {
    int width, height;
    glfwGetWindowSize(window, &width, &height);
    glReadBuffer(GL_FRONT);// フロントを読み込む様に設定する
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    unsigned char* data = new unsigned char[width*height * 4];
    glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, data);
    System::IntPtr scan0(data);
    Bitmap ^bitmap = gcnew Bitmap(width, height, width * 4, Imaging::PixelFormat::Format32bppArgb, scan0);
    bitmap->Save("capture.png");
}

gcnew Bitmap(width, height, stride, Imaging::PixelFormat::Format32bppArgb, scan0);

stride=width*4
にすることによて、RGBA4個であることを知らせます。

サンプルプログラム

git/PNGCaptureにあります。
レンダリング結果をpngで出力するプログラム。
背景は透明。
キーボードのcを押すとキャプチャします。
output.pngという名前で出力されます。
外部ライブラリとして
OpenCV 2.X
glfw
が必要です。
その他の足りないヘッダはmiffyフォルダからとってください。


framebuffer makeimage screenshot


ファイル

サポートサイト Wikidot.com framebuffermakeimagescreenshot