土と悪魔の両方の画像ライブラリを使用してみましたが、作成されたスクリーンショットは完全に黒い画像です。悪魔の場合、ここにある機能を使用しましたopenGLでスクリーンショットを撮り、pngとして保存しますが、画像はまだ黒い画面です。
スクリーンショットの保存または OpenGL 出力のエクスポートに関するアイデアはありますか?
土と悪魔の両方の画像ライブラリを使用してみましたが、作成されたスクリーンショットは完全に黒い画像です。悪魔の場合、ここにある機能を使用しましたopenGLでスクリーンショットを撮り、pngとして保存しますが、画像はまだ黒い画面です。
スクリーンショットの保存または OpenGL 出力のエクスポートに関するアイデアはありますか?
これを試して:
#include <vector>
#include <GL/glut.h>
#include <SOIL/SOIL.h>
using namespace std;
bool save = false;
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, -1, 1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub( 255, 0, 0 );
glBegin( GL_QUADS );
glVertex2i( -1, -1 );
glVertex2i( 1, -1 );
glVertex2i( 1, 1 );
glVertex2i( -1, 1 );
glEnd();
if( save )
{
int w = glutGet( GLUT_WINDOW_WIDTH );
int h = glutGet( GLUT_WINDOW_HEIGHT );
vector< unsigned char > buf( w * h * 3 );
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
glReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, &buf[0] );
int err = SOIL_save_image
(
"img.bmp",
SOIL_SAVE_TYPE_BMP,
w, h, 3,
&buf[0]
);
save = false;
}
glutSwapBuffers();
}
void keyboard( unsigned char key, int x, int y )
{
if( key == 's' )
{
save = true;
glutPostRedisplay();
}
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMainLoop();
return 0;
}
OpenGL レンダリングからスクリーンショットを保存する際の最大の問題は、通常のシステム ウィンドウ (通常は OpenGL の描画キャンバスとして使用する) のフレームバッファが、データのソースとして非常に信頼できないことです。他のウィンドウによって (部分的に) 遮られている場合、一部の部分には定義されたデータがまったく含まれていない可能性があります。バッファスワップの後、バックバッファの内容は未定義などです。
いくつかの基本的なルール:
通常のウィンドウからスクリーンショットをキャプチャする場合は、いずれかからキャプチャします。
描画が終了した直後で、バッファ スワップの前のバック バッファ (glReadPixels は、同期ポイントを導入するため、パイプライン内のすべての描画操作のフラッシュと終了を意味します)
バッファスワップ後のフロントバッファ
OpenGL レンダリングの信頼できるキャプチャを取得するには、フレームバッファ オブジェクトにレンダリングする必要があります。そこでは、画像が明確に定義されており、ウィンドウの無効化とアニメーション ループの間の競合状態やその他の奇妙な状況で、トレースやデバッグが困難な場合でも「消える」ことはありません。画像を表示するには、FBO からメイン フレーム バッファにブリットします。
genpfaultの回答はうまく機能しますが、よりクリーンなソリューションにつながりました。
if (!SOIL_save_screenshot("screenshot.bmp",
SOIL_SAVE_TYPE_BMP, 0, 0, width, height)) {
// Handle error here
}
こうすることで、バッファや call などを設定する必要がglReadPixels
なくなります。SOIL はそれらすべてを自動的に処理します!
また、pslayer89 のコメントに対する genpfault の応答に従ってSOIL_FLAG_INVERT_Y
、2 番目のパラメーターで渡されるフラグに追加する必要があることに注意してください (射影/モデル マトリックスで Y 軸を既に反転している場合を除きます)。