GL屏幕截图视口上的中断调整大小...有时候

时间:2016-05-19 16:19:03

标签: c++ opengl screenshot bmp

我正在开发一个SIMDIS插件(基本上是军用谷歌地球),使用VS 2012用c ++编写。这是一个非常漂亮的小东西,自动绘制点,其功能之一是采取一系列的截图view-port并保存图像,以便在其他地方使用/处理。这也可以正常工作......直到你重新调整视口大小太多次。通过单击窗口的一角并将其拖得越来越大来重新调整大小,程序可以启动全屏或窗口模式;无论哪种方式,它可以在前几组中正常工作......或者只要窗口没有重新调整大小。

当它打破时,程序仍然会愉快地前进,创建文件,并为我想要生成的任何分辨率图像的适当大小填充数据...但格式变得不好。它仍然是* .bmp,但是窗口停止能够理解它。虽然没有错误,但是(我认为,我没有发现任何GL错误?[如果可能的话?])。

我无法通过特定数量的操作始终如一地发生这种情况,但似乎在3-7个视口重新调整大小后开始失败。我不知道这是我的截图代码,SIMDIS程序或插件的问题,GL问题,还是什么问题。我在多台机器上测试过它。

之前有没有人遇到这个问题?有什么具体的我应该做的,我不是吗?这是父程序(SIMDIS)的原生问题,还是我可以使用我不知道的GL命令处理/解决的问题?

截图代码如下:

#include "TakeScreenshot.h"  //has "#include <gl/GL.h>" etc...

TakeScreenshot::TakeScreenshot()
{   
}


std::vector<int> * TakeScreenshot::TakeAScreenshotBMP(const char* filename)
{
    //std::cout << "Screenshot! "; 
    std::vector<int> * returnVec = new std::vector<int>();

    int VPort[4] = {0,0,0,0};
    int FSize = 0;
    int PackStore = 0;

    //get GL viewport dimensions, x,y,w,h into vport
    glGetIntegerv(GL_VIEWPORT,VPort);

    //make a framebuffer, RGB
    FSize = VPort[2]*VPort[3]*3;

    unsigned char PStore[8294400];// 4k sized buffer

    //store settings
    glGetIntegerv(GL_PACK_ALIGNMENT, &PackStore);

    //unpack to byte order
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    //read the gl buffer into our buffer 
    glReadPixels(VPort[0],VPort[1],VPort[2],VPort[3],GL_RGB,GL_UNSIGNED_BYTE,&PStore);

    //Pass back settings
    glPixelStorei(GL_PACK_ALIGNMENT, PackStore);


    ///
    //set up file info
    ///

    BITMAPINFOHEADER BMIH; //info header
    BMIH.biSize = sizeof(BITMAPINFOHEADER);
    BMIH.biSizeImage= VPort[2] * VPort[3] * 3;

    BMIH.biWidth = VPort[2];
    BMIH.biHeight = VPort[3];
    BMIH.biPlanes = 1;
    BMIH.biBitCount = 24;
    BMIH.biCompression = BI_RGB;

    BITMAPFILEHEADER bmfh;//file header
    int nBitsOffset = sizeof(BITMAPFILEHEADER) + BMIH.biSize;
    LONG lImageSize = BMIH.biSizeImage;
    LONG lFileSize = nBitsOffset + lImageSize;
    bmfh.bfType = 'B' + ('M'<<8);
    bmfh.bfOffBits = nBitsOffset;
    bmfh.bfSize = lFileSize;
    bmfh.bfReserved1 = bmfh.bfReserved2 = 0;


    // swap r and b values because GL has them backwards for BMP format.
    unsigned char SwapByte;
    for(int loop = 0; loop<FSize; loop+=3)
    {
        SwapByte = PStore[loop];
        PStore[loop] = PStore[loop+2];
        PStore[loop +2] = SwapByte;
    }

    ///
    // File writing section
    ///


    FILE *pFile;
    pFile = fopen(filename, "wb");
    //if something borked

    if(pFile == NULL)
    {
        std::cout << "TakeScreenshot::TakeAScreenshotBMP>> Error; was not able to create file (Permisions?)" << std::endl;
        returnVec->push_back(-1);
        returnVec->push_back(-1);
        return returnVec; //exit
    }


    UINT nWrittenFileHeaderSize = fwrite(&bmfh,1,sizeof(BITMAPFILEHEADER), pFile);
    UINT nWrittenInfoHeaderSize = fwrite(&BMIH,1,sizeof(BITMAPINFOHEADER), pFile);
    UINT nWrittenDIBDataSize = fwrite(&PStore, 1, lImageSize, pFile);

    fclose(pFile);

    //some return data for processing later
    returnVec->push_back(VPort[2]);
    returnVec->push_back(VPort[3]);
    return returnVec;
}


TakeScreenshot::~TakeScreenshot(void)
{
}

0 个答案:

没有答案