注册 登录
编程论坛 Android开发

openGL帧缓存读取,恳请高高手指点

yonghu00fa 发布于 2013-06-06 15:47, 1890 次点击
openGL新手,请教~~
问题描述:

 想把自己openGL程序中渲染出的结果从帧缓存中读出来,并且存储成.BMP格式的文件,使用了网上的代码:
#define BITMAP_ID 0x4D42        // the universal bitmap ID
int bmpIndex = 0;
char outFileName[256] = {0};

bool screenshot(const char* filename)
{
    GLenum lastBuffer;//无符号整数
    GLbyte* pBits = 0; // 图像数据
    unsigned long lImageSize;
    GLint iViewport[4]; // 视图大小

    glGetIntegerv(GL_VIEWPORT, iViewport);// 获取视图大小
    lImageSize = iViewport[2] * iViewport[3] * 3;  //窗口长宽相乘,计算像素数,再乘以通道数3

    pBits = (GLbyte*)new unsigned char[lImageSize];//分配足以存放窗口图像的空间
    if (!pBits)
    return false;

    // 从color buffer中读取数据
    glPixelStorei(GL_PACK_ALIGNMENT, 4);   
    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

    //
    glGetIntegerv(GL_READ_BUFFER, (GLint*)&lastBuffer);
    glReadBuffer(GL_FRONT);
    glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, pBits);
    glReadBuffer(lastBuffer);

    bool haveRead = 0;
    haveRead = writeBMP(filename,(unsigned char*)pBits,iViewport[2],iViewport[3]);

    if (haveRead)
        return true;
    else
        return false;

}

bool writeBMP(const char filename[],unsigned char* data,unsigned int w,unsigned int h)
{
    std::ofstream out_file;

    ////** 检查data */
    if(!data)
    {
    std::cerr << "data corrupted! " << std::endl;
    out_file.close();
    return false;
    }

    ////** 创建位图文件信息和位图文件头结构 */
    BITMAPFILEHEADER header;
    BITMAPINFOHEADER bitmapInfoHeader;

    //unsigned char textureColors = 0;/**< 用于将图像颜色从BGR变换到RGB */

    ///** 打开文件,并检查错误 */
    out_file.open(filename, std::ios::out | std::ios::binary);
    if (!out_file)
    {
    std::cerr << "Unable to open file " << filename << std::endl;
    return false;
    }

    ////** 填充BITMAPFILEHEADER */
    header.bfType = BITMAP_ID;
    header.bfSize = w*h*3 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    header.bfReserved1 = 0;
    header.bfReserved2 = 0;
    header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    ////** 写入位图文件头信息 */
    out_file.write((char*)&header, sizeof(BITMAPFILEHEADER));

    ////** 填充BITMAPINFOHEADER */
    bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitmapInfoHeader.biWidth = w;
    bitmapInfoHeader.biHeight = h;
    bitmapInfoHeader.biPlanes = 1;
    bitmapInfoHeader.biBitCount = 24;
    bitmapInfoHeader.biCompression = BI_RGB; // BI_RLE4 BI_RLE8
    bitmapInfoHeader.biSizeImage = w * h * 3; // 当压缩类型为BI_RGB是也可以设置为0
    bitmapInfoHeader.biXPelsPerMeter = 0;
    bitmapInfoHeader.biYPelsPerMeter = 0;
    bitmapInfoHeader.biClrUsed = 0;
    bitmapInfoHeader.biClrImportant = 0;
    ////** 写入位图文件信息 */
    out_file.write((char*)&bitmapInfoHeader, sizeof(BITMAPINFOHEADER));

    ////** 将指针移到数据开始位置 */
    out_file.seekp(header.bfOffBits, std::ios::beg);

    ////** 写入图像数据 */
    out_file.write((char*)data, bitmapInfoHeader.biSizeImage);

    out_file.close();
    return true;
}

    发现读出来的图片是当前屏幕显示的内容,也就是说只有我的应用程序中的生成的窗口在屏幕最前面时,存储的图片才会是的想要的,如果我的程序生成的窗口不在屏幕最前端,存储图片得到的内容为当前看到的屏幕内容。这样我就不能控制我所得到的图片只是我的程序渲染窗口内的内容。

我查看了openGL帧缓存相关的文献,发现openGL和系统使用了同一个缓存,而不是给应用程序专门开辟了专门的缓存。不知我的理解是否正确?

请教大侠,怎样才能访问自己编写的openGL应用程序专用帧缓存,得到自己应用程序窗口的画面?

多谢了!!!!!
1 回复
#2
yonghu00fa2013-06-06 19:37
经过试验,将glReadBuffer(GL_FRONT)改为glReadBuffer(GL_BACK),在不最小化自己应用程序生成的窗口情况下,能够得到自己程序渲染的场景。最小化自己的窗口之后,就得不到完整的图片。

进一步多个openGL窗口的情况暂时没有时间去测试,请各位实验并不惜赐教!
1