EGL PixmapSurface实验笔记

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

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

在EGL中最好还是别用PixmapSurface了,因为这个是完全依赖于EGL的具体实现,没有固定的标准说一定要实现这个东西,而且与本地Bitmap的兼容性如何不知道。尝试了很多方法都没有成功。对自己的实验做个简单潦草的笔记。

 

如果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. 

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

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.

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

再来看这一段

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.

虽然pixmapsurface可能不被支持。但是我不知道有什么方法可直接获得我的EGL OGLES实现是否支持。

反正不管了,我用最笨的方式测试,不停的改变参数,不停的打印,不停的保存位图,查看被保存的位图。 其实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);

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

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 &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 &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 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(&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;
}

转载于:https://my.oschina.net/sweetdark/blog/207334

你可能感兴趣的:(EGL PixmapSurface实验笔记)