I have tried using both soil and devil image libraries but the screenshots created are completely black images. For devil I used the function found here Take screenshot with openGL and save it as png but the image is still black screen.
Any ideas about saving screenshot or exporting opengl output?
Try this:
#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;
}
The biggest problem when saving screenshots from OpenGL renderings is, that the framebuffer of a regular system Window (which you normally use as drawing canvas for OpenGL) is a extremely unreliable source for data. If it's (partially) occluded by other windows some parts may contain no defined data at all. After a buffer swap the contents of the back buffer are undefined, etc. etc.
A few basic rules:
If capturing screenshots from the regular window, capture them from either
the back buffer right after the drawing finished but before the buffer swap (glReadPixels implieas a flush and finish of all drawing operations in the pipeline, as it introduces a synchronization point)
the front buffer after the buffer swap
To get reliable captures of OpenGL renderings, you should render to a framebuffer object. There the image is well defined and will not "vanish" in some hard to trace and debug race conditions between window invalidations and animation loops or other weird situations. To display the picture you then blit from the FBO to the main framebuffer.
来源:https://stackoverflow.com/questions/17370828/save-opengl-output-using-devil-or-soil