Save openGL output using DevIL or SOIL

爱⌒轻易说出口 提交于 2019-12-02 07:13:41

问题


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?


回答1:


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;
}



回答2:


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!