我是在vc++环境下的。
我用来显示的窗口用的是OpenGL自带的库函数创建的,我想将我窗口渲染出来的画面在程序的文档下面以位图的格式保存。我知道应该是现有glReadPixels()函数先读取帧缓冲区的像素信息,用保存信息的数组来绘制这个位图,在绘制之后将其保存在目录下。
高手们,我该如何创建这个位图文件呢?如何些这个位图类,如何创建呢?最好有代码能让我参考下,或者介绍写入手的方法,谢谢

解决方案 »

  1.   

    创建位图还不简单,如果用MFC的话就用CBitmap::CreateBitmap,如果没有MFC就用CreateBitmapBOOL CBitmap::CreateBitmap(
       int nWidth,
       int nHeight,
       UINT nPlanes,
       UINT nBitcount,
       const void* lpBits 
    );
    HBITMAP CreateBitmap(
      int nWidth,         // bitmap width, in pixels
      int nHeight,        // bitmap height, in pixels
      UINT cPlanes,       // number of color planes
      UINT cBitsPerPel,   // number of bits to identify color
      CONST VOID *lpvBits // color data array
    );
      

  2.   

    不用MFC!
    HBITMAP CreateBitmap( 
      int nWidth,        // bitmap width, in pixels 
      int nHeight,        // bitmap height, in pixels 
      UINT cPlanes,      // number of color planes 
      UINT cBitsPerPel,  // number of bits to identify color 
      CONST VOID *lpvBits // color data array 
    );
    这个就可以创建一个空的位图吗?那么他的文件名和他存储的路径怎么指定呢
      

  3.   

    CreateBitmap就是根据参数创建出来一个空的位图,它所创建的是内存位图,要保存文件之前先生成这个.
    如果要保存为文件的话需要自己写代码,Windows API只提供了读取位图的函数没提供保存位图的函数.不过Windows 的位图格式是公开的,自己写一个代码没有多困难,实在不愿意还有很多免费的库可以用
      

  4.   

    http://www.geocities.com/foetsch/screenshot/screenshot.htm
    可以参考一下这个
      

  5.   

    还是不明白!
    流程是这样的,我用OpenGL渲染了一个场景,我想,通过一个按键的控制(这个好实现)在程序目录下直接生成一个位图文件,让后将我渲染的场景的像素信息传个这个位图,使我运行完后,可以在我程序的目录下找到这些刚生成的这些场景位图。
    是否是先些以DIB的位图类呢?如何写比较好呢,怎么去写这个随时生成一个位图并命名的成员函数呢?望高手们指教!!!!!
      

  6.   

                    CRect rect;
    GetClientRect(&rect);
    CSize size(rect.Width(),rect.Height());
    ASSERT(size.cx > 0);
    ASSERT(size.cy > 0);
    TRACE("Start reading client...\n");
    TRACE("Client : (%d,%d)\n",size.cx,size.cy);
    unsigned char *pixel = new unsigned char[3*size.cx*size.cy];
    ASSERT(pixel != NULL);
    CRect ClientRect,MainRect;
    this->GetWindowRect(&ClientRect);
    CWnd *pMain = AfxGetApp()->m_pMainWnd;
    CWindowDC dc(pMain);
    pMain->GetWindowRect(&MainRect);
    int xOffset = ClientRect.left - MainRect.left;
    int yOffset = ClientRect.top - MainRect.top;
    for(int j=0;j<size.cy;j++)
    for(int i=0;i<size.cx;i++)
    {
    COLORREF color = dc.GetPixel(i+xOffset,j+yOffset);
    pixel[3*(size.cx*(size.cy-1-j)+i)] = (BYTE)GetBValue(color);
    pixel[3*(size.cx*(size.cy-1-j)+i)+1] = (BYTE)GetGValue(color);
    pixel[3*(size.cx*(size.cy-1-j)+i)+2] = (BYTE)GetRValue(color);
    }
    int rest=(size.cx*3)%4;
    unsigned int Width32;
    if(rest != 0)
    Width32=(size.cx*3 + 4-rest);
    else
    Width32=(size.cx*3);
    unsigned int BytePerPixel = 3;

    unsigned char *pData = new unsigned char [Width32 * size.cy];
    for(j=0;j<size.cy;j++)
    for(int i=0;i<size.cx;i++)
    for(int k=0;k<BytePerPixel;k++)
    {
    pData[Width32*j + i*BytePerPixel+k] = 
     pixel[(size.cx*j+i)*BytePerPixel+k];
    //TRACE("pixel : %d\n",(int)buffer[(width*j+i)*BytePerPixel+k]);
    } // Cleanup memory
    delete [] pixel;
    BITMAPINFOHEADER header;
    header.biWidth=size.cx;
    header.biHeight=size.cy;
    header.biSizeImage=Width32*size.cy;
    header.biSize=40;
    header.biPlanes=1;
    header.biBitCount=24;
    header.biCompression=0;
    header.biXPelsPerMeter=0;
    header.biYPelsPerMeter=0;
    header.biClrUsed=0;
    header.biClrImportant=0; BITMAPFILEHEADER bfh;
    bfh.bfType=0X4D42;
    bfh.bfSize=54+Width32*size.cy;
    bfh.bfReserved1=0;
    bfh.bfReserved2=0;
    bfh.bfOffBits=54;

                    FILE *fA=fopen(openname,"wb");
    fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fA);
                    fwrite(&header,sizeof(BITMAPINFOHEADER),1,fA);
    fwrite(pData, Width32 * size.cy,1,fA);
    fclose(fA);

    TRACE("ok\n");
    试试这个,直接读取帧缓存的。不过感觉不如直接生成个DIB区然后用onpaint绘制在里边来得好。
      

  7.   

    刚没看清楚,用opengl自带的窗口显示的话也可以读取帧缓存,跟上边一样保存到数组内,然后设置BITMAPFILEHEADER及BITMAPINFOHEADER的信息,用"wb"模式写入文件中.不过读取帧缓存的时候可能需要转换下颜色。
      

  8.   

    我重新说明一下:我现在是需要一个32位的位图类,里面主要含有这两个成员函数:一个在工程目录下创建一个我所需规格的位图(可以通过参数或者在初始化中预先设置好都可以)、另一个就是可以接受我用glReadPixels()读取出来的OpenGL帧缓冲区中关于保存了渲染图像的像素信息的那个数组。
    本人没有接触过关于位图的这方面,看了看书有讲到这方面可是要修改就无从下手了。所以加分跪求代码或详细指点!
    本人邮箱[email protected]
    在线等谢谢了!
      

  9.   

    首先你需要了解一下位图的文件结构WINDOWS下可以用
    typedef struct tagBITMAP_FILE{   BITMAPFILEHEADER bitmapheader;
      BITMAPINFOHEADER bitmapinfoheader;
      PALETTEENTRY palette[256];
      UCHAR *buffer;   //UCHAR 大小 同 INT (16BYTES)在VC6下}
    这样一个结构封装的.然后你看看位图的读写操作,网上看看别人是怎么实现的.把信息保存到这个结构的一个实例里,直接写入一个空的后缀BMP的文件就应该可以了
      

  10.   

    http://www.lonesock.net/soil.html
    不如使用一下库吧
    SOIL_save_screenshot调用一下就搞定,你也可以看下他的源码是怎么实现的
      

  11.   

    哪位大哥帮帮忙  我想用OpenGL在VC上画的图怎么把整个图都保存下来,包括屏幕未显示的部分
      

  12.   

    void glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,   GLenum format, GLenum type, GLvoid *pixels );  读取图像数据到pixels,然后使用cximage库直接保存为图像(支持bmp)。另一种方式是使用mesa(opengl的另一种实现),用mesa api可以直接把数据画在内存里。
     OSMesaContext ctx;
    OSMesaCreateContextExt()
    OSMesaMakeCurrent()//这里指定buffer
    ...
    最后保存buffer为相应格式图片就好了