EGL PixmapSurface实验笔记

EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLInt *attr_list)app

在EGL中最好仍是别用PixmapSurface了,由于这个是彻底依赖于EGL的具体实现,没有固定的标准说必定要实现这个东西,并且与本地Bitmap的兼容性如何不知道。尝试了不少方法都没有成功。对本身的实验作个简单潦草的笔记。ide

 

若是config中不支持渲染到pixmap 即 config中的EGL_SURFACE_TYPE中没有包含EGL_PIXMAP_BIT。那么也会返回EGL_BAD_MATCH错误。测试

You also need to ensure that EGL_SURFACE_TYPE in your EGL configuration is set toEGL_PIXMAP_BIT. Again, the last parameter is reserved for surface attributes. ui

我在config_list中加入了EGL_PIXMAP_BIT的支持,但仍是不行。spa

EGL pixmaps are not actual entities. They are an EGL abstraction of an already existing native pixmap. A call to eglCreatePixmapSurface does not allocate any memory or create a pixmap. It only "wraps" a pre-existing pixmap in an EGL structure. If the implementation of EGL you are using defines an egl native pixmap as being a QTPixmap, then you should have no problems "wrapping" that pixmap using eglCreatePixmapSurface. If not, you need to (re)implement eglCreatePixmapSurface to accept QTPixmaps as the native pixmap type..net

在网上看到人说 pixmaps并非一个真正的实体,而是对传进来的本地pixmap的一种包装。code

再来看这一段orm

Pixmaps are another type of off-screen rendering surface that can be allocated by the EGL driver. The EGL specification (Khronos Native Platform Graphics Interface) defines two types of off-screen rendering surfaces; pixelbuffers and pixmaps (as well as the framebuffer used for the on-screen native platform windowing system). The difference between pixelbuffers and pixmaps is in the format and stride of the image data they store. PixelBuffers are created with a format and stride that the SGX can render into efficiently, but is not necessarily compatible with any other graphics interface beyond OpenGL ES 1.1 and OpenVG. Pixmaps, however are specifically defined to be compatible with the native windowing and/or graphics system for the OS platform that the EGL driver is implemented for. Also, since pixelbuffers are required by the EGL specification, their support is guaranteed on whatever OS platform the EGL driver is provided for. However, support for pixmaps is optional and should not be assumed because a different implementation is required for each windowing system.blog

虽然pixmapsurface可能不被支持。可是我不知道有什么方法可直接得到个人EGL OGLES实现是否支持。ci

反正无论了,我用最笨的方式测试,不停的改变参数,不停的打印,不停的保存位图,查看被保存的位图。 其实EGLDisplay保存位图没有成功过。到时本地的HDC能够保存位图,不过opengl画的东西好像都没有贴到本地的设备上下文环境hdc上。

下面是初始化的代码

   

EGLint config_list[] = {
        EGL_RED_SIZE,       8,
        EGL_GREEN_SIZE,     8,
        EGL_BLUE_SIZE,      8,
        EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_WINDOW_BIT,//EGL_NATIVE_RENDERABLE, EGL_TRUE,   有这个选项的话 eglCreateWindowSurface 建立surface不成功,不知道是否是跟机器有关        
        EGL_DEPTH_SIZE,     24,    
        EGL_NONE
    };



EGLint num_config;

    
    g_dpy = GetDC(gHWND);

    display = eglGetDisplay(g_dpy);if (eglInitialize(display, NULL, NULL) == EGL_FALSE || eglGetError() != EGL_SUCCESS)
    {
        OutputError();
        printf("eglInitialize Error!\r\n");return;
    }

    eglChooseConfig(display, config_list, &config, 1, &num_config);

    eglBindAPI(EGL_OPENGL_ES_API);

    surface = eglCreateWindowSurface( display, config, (NativeWindowType)(gHWND) , NULL);if ( surface == EGL_NO_SURFACE )
    {
      OutputError();
        printf("eglCreateWindowSurface Error!\r\n");return ;
    }
…省略初始化context

首先bitmap = CreateCompatibleBitmap((HDC)display, width, height); 返回的bitmap一直不成功。

bitmap = CreateCompatibleBitmap((HDC)g_dpy, width, height); 则是能够的。

随便画点东西测试

 glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, width, height, 0, -1.0, 10.0);float v[] = {0.0f, 100.0f, 20.0f, 100.0f, -10.0f, 10.0f, 35.0f, 55.0f };

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -10.0f);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, v);
    glDrawArrays(GL_LINE_LOOP, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glFlush ();
    eglSwapBuffers(display, surface);//WriteBmp2(("E:\\winsave1.bmp"), (HDC)display);// 这个没法兼容,一直没成功保存过WriteBmp2(("E:\\winsave2.bmp"), (HDC)g_dpy);

image

为此我把这些g_dpy的位图保存为文件倒是下面的这个样子的。因而可知虽然display是根据g_dpy建立的,但好像根本没有关系,在eglSwapBuffer把画好的东西交换到display中,并不影响g_dpy的内容。

image

bitmap = CreateCompatibleBitmap((HDC)g_dpy, width, height);
   pixsurface = eglCreatePixmapSurface(display, config, (EGLNativePixmapType)bitmap, NULL);

   glClearColor( 1.0f, 0.0f, 0.0f, 1.0f );        // RedglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    memdc  = CreateCompatibleDC( (HDC)g_dpy );
    HBITMAP bitMap2 = CreateCompatibleBitmap((HDC)display, width, height);
    HBITMAP bitMap3 = CreateBitmap(width, height, 1, 32, NULL);
    glFlush();
    eglCopyBuffers( display, pixsurface , bitMap3 ); //不管使用哪一个bitmap bitmap2 bitmap3运行到这句必然报错,访问了0x00000的地址。无解,不知道为何。
glClearColor( 0.0f, 1.0f, 0.0f, 1.0f );        // GreenglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glFinish();
    glFlush();
    WriteBmp2(("E:\\greensave1.bmp"), (HDC)display);
    eglSwapBuffers(display, surface);
    WriteBmp2(("E:\\greensave.bmp"), (HDC)display)

还试了不少种其余的方式都不行,都保存不了display的位图。

我想个人电脑可能不支持这种方式,或者个人库不支持。


保存位图的方法是转自:http://blog.csdn.net/norains/article/details/4594514

#ifdef UNICODE
    #ifndef TSTRING#define TSTRING std::wstring#endif#else#ifndef TSTRING#define TSTRING std::string#endif#endifBOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg);
BOOL WriteBmp(const TSTRING &strFile,HDC hdc);
BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC);

BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg) 
{     

    BITMAPINFOHEADER bmInfoHeader = {0};
    bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmInfoHeader.biWidth = sizeImg.cx;
    bmInfoHeader.biHeight = sizeImg.cy;
    bmInfoHeader.biPlanes = 1;
    bmInfoHeader.biBitCount = 24;//Bimap file header in order to write bmp fileBITMAPFILEHEADER bmFileHeader = {0};
    bmFileHeader.bfType = 0x4d42;  //bmp  bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if(hFile == INVALID_HANDLE_VALUE)
    {return FALSE;
    }

    DWORD dwWrite = 0;
    WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
    WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
    WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);


    CloseHandle(hFile);return TRUE;
} 


BOOL WriteBmp(const TSTRING &strFile,HDC hdc)
{int iWidth = GetDeviceCaps(hdc,HORZRES);int iHeight = GetDeviceCaps(hdc,VERTRES);
    RECT rcDC = {0,0,iWidth,iHeight};return WriteBmp(strFile,hdc,rcDC);    
}

BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC)
{
    BOOL bRes = FALSE;
    BITMAPINFO bmpInfo = {0};
    BYTE *pData = NULL;
    SIZE sizeImg = {0};
    HBITMAP hBmp = NULL;
    std::vector<BYTE> vtData;
    HGDIOBJ hOldObj = NULL;
    HDC hdcMem = NULL;//Initilaize the bitmap information    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = rcDC.right - rcDC.left;
    bmpInfo.bmiHeader.biHeight = rcDC.bottom - rcDC.top;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 24;//Create the compatible DC to get the datahdcMem = CreateCompatibleDC(hdc);if(hdcMem == NULL)
    {goto EXIT;
    }//Get the data from the memory DC    hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);if(hBmp == NULL)
    {goto EXIT;
    }
    hOldObj = SelectObject(hdcMem, hBmp);    //Draw to the memory DCsizeImg.cx = bmpInfo.bmiHeader.biWidth;
    sizeImg.cy = bmpInfo.bmiHeader.biHeight;
    StretchBlt(hdcMem,
                0,
                0,
                sizeImg.cx,
                sizeImg.cy,
                hdc,
                rcDC.left,
                rcDC.top,
                rcDC.right - rcDC.left + 1,
                rcDC.bottom - rcDC.top + 1,
                SRCCOPY);
    

    vtData.resize(sizeImg.cx * sizeImg.cy * 3);
    memcpy(&vtData[0],pData,vtData.size());
    bRes = WriteBmp(strFile,vtData,sizeImg);

    SelectObject(hdcMem, hOldObj);
    

EXIT:if(hBmp != NULL)
    {
        DeleteObject(hBmp);
    }if(hdcMem != NULL)
    {
        DeleteDC(hdcMem);
    }return bRes;
}
相关文章
相关标签/搜索