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);
爲此我把這些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<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; }