glReadPixels为空时如何生成屏幕截图? [英] How can I generate a screenshot when glReadPixels is empty?

查看:172
本文介绍了glReadPixels为空时如何生成屏幕截图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序在使用OpenGL的窗口中运行(带freeglut 2.8.1的VS2012).基本上在每个时间步(通过从glutIdleFunc钩子调用glutPostRedisplay来运行),我都调用自己的draw函数,然后调用glFlush以显示结果.然后,我调用自己的screenShot函数,该函数使用glReadPixels函数将像素转储到tga文件中.

I have a program which runs in a window using OpenGL (VS2012 with freeglut 2.8.1). Basically at every time step (run via a call to glutPostRedisplay from my glutIdleFunc hook) I call my own draw function followed by a call to glFlush to display the result. Then I call my own screenShot function which uses the glReadPixels function to dump the pixels to a tga file.

此设置的问题是,当窗口最小化时,文件为空.也就是说,glReadPixels的输出为空;如何避免这种情况?

The problem with this setup is that the files are empty when the window gets minimised. That is to say, the output from glReadPixels is empty; How can I avoid this?

这是我正在使用的screenShot函数的副本(我不是版权所有者):

Here is a copy of the screenShot function I am using (I am not the copyright holder):

//////////////////////////////////////////////////
// Grab the OpenGL screen and save it as a .tga //
// Copyright (C) Marius Andra 2001              //
// http://cone3d.gz.ee  EMAIL: cone3d@hot.ee    //
//////////////////////////////////////////////////
// (modified by me a little)
int screenShot(int const num)
{
    typedef unsigned char uchar;
    // we will store the image data here
    uchar *pixels;
    // the thingy we use to write files
    FILE * shot;
    // we get the width/height of the screen into this array
    int screenStats[4];

    // get the width/height of the window
    glGetIntegerv(GL_VIEWPORT, screenStats);

    // generate an array large enough to hold the pixel data 
    // (width*height*bytesPerPixel)
    pixels = new unsigned char[screenStats[2]*screenStats[3]*3];
    // read in the pixel data, TGA's pixels are BGR aligned
    glReadPixels(0, 0, screenStats[2], screenStats[3], 0x80E0, 
    GL_UNSIGNED_BYTE, pixels);

    // open the file for writing. If unsucessful, return 1
    std::string filename = kScreenShotFileNamePrefix + Function::Num2Str(num) + ".tga";

    shot=fopen(filename.c_str(), "wb");

    if (shot == NULL)
        return 1;

    // this is the tga header it must be in the beginning of 
    // every (uncompressed) .tga
    uchar TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};
    // the header that is used to get the dimensions of the .tga
    // header[1]*256+header[0] - width
    // header[3]*256+header[2] - height
    // header[4] - bits per pixel
    // header[5] - ?
    uchar header[6]={((int)(screenStats[2]%256)),
    ((int)(screenStats[2]/256)),
    ((int)(screenStats[3]%256)),
    ((int)(screenStats[3]/256)),24,0};

    // write out the TGA header
    fwrite(TGAheader, sizeof(uchar), 12, shot);
    // write out the header
    fwrite(header, sizeof(uchar), 6, shot);
    // write the pixels
    fwrite(pixels, sizeof(uchar), 
    screenStats[2]*screenStats[3]*3, shot);

    // close the file
    fclose(shot);
    // free the memory
    delete [] pixels;

    // return success
    return 0;
}

那么无论Windows是否决定在监视器上实际显示内容,我如何将屏幕截图打印到TGA文件中?

So how can I print the screenshot to a TGA file regardless of whether Windows decides to actually display the content on the monitor?

注意:因为我试图保持仿真进度的可视记录,所以我需要打印每帧,无论是否渲染.我意识到最后的陈述有点矛盾,因为我需要渲染框架以产生屏幕抓图.改写我需要glReadPixels(或某些替代功能)在每一步产生程序的更新状态,以便无论窗口是否选择显示它,我都可以将其打印到文件中.

Note: Because I am trying to keep a visual record of the progress of a simulation, I need to print every frame, regardless of whether it is being rendered. I realise that last statement is a bit of a contradiction, since I need to render the frame in order to produce the screengrab. To rephrase; I need glReadPixels (or some alternative function) to produce the updated state of my program at every step so that I can print it to a file, regardless of whether windows will choose to display it.

推荐答案

听起来像您正在渲染为 FBO ,然后使用glReadPixels()从中提取图像的前缓冲区.

Render to a FBO and use glReadPixels() to slurp images out of that instead of the front buffer.

这篇关于glReadPixels为空时如何生成屏幕截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆