OpenGL ES2需要的库:libGLESv2, libEGL
其中libEGL是用于和不同系统的窗口打交道的,是一个标准。如果需要让你显示在窗口中,如调用eglCreateWindowSurface;若off-screen,则eglCreatePbufferSurface。
直接上一下代码:
void esInitContext(ESContext *esContext) { if ( esContext != NULL ) { memset( esContext, 0, sizeof( ESContext) ); } } GLboolean esCreateOffScreen( ESContext *esContext, GLint width, GLint height) { EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; EGLDisplay display; EGLContext context; EGLSurface surface; EGLConfig config; EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE }; EGLint cfgAttribs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 1, EGL_NONE }; EGLint PBufAttribs[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_LARGEST_PBUFFER, EGL_TRUE, EGL_NONE }; // Get Display display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if ( display == EGL_NO_DISPLAY ) { return EGL_FALSE; } // Initialize EGL if ( !eglInitialize(display, &majorVersion, &minorVersion) ) { return EGL_FALSE; } // Get configs if ( !eglGetConfigs(display, NULL, 0, &numConfigs) ) { return EGL_FALSE; } // Choose config if ( !eglChooseConfig(display, cfgAttribs, &config, 1, &numConfigs) ) { return EGL_FALSE; } // Create a surface //surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, NULL); //surface = eglCreatePixmapSurface(display, config, pixmap, NULL); surface = eglCreatePbufferSurface(display, config, PBufAttribs); if ( surface == EGL_NO_SURFACE ) { return EGL_FALSE; } // Check to see what size pbuffer we were allocated EGLint os_width; EGLint os_height; if(!eglQuerySurface(display, surface, EGL_WIDTH, &os_width) || !eglQuerySurface(display, surface, EGL_HEIGHT, &os_height)) { return EGL_FALSE; } // Create a GL context context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs ); if ( context == EGL_NO_CONTEXT ) { return EGL_FALSE; } ; // Make the context current if ( !eglMakeCurrent(display, surface, surface, context) ) { return EGL_FALSE; } esContext->eglContext = context; esContext->eglDisplay = display; esContext->eglSurface = surface; esContext->width = os_width; esContext->height = os_height; } void esDipose(ESContext *esContext) { if(esContext->eglContext != EGL_NO_CONTEXT) eglDestroyContext(esContext->eglDisplay, esContext->eglContext); if(esContext->eglSurface != EGL_NO_SURFACE) eglDestroySurface(esContext->eglDisplay, esContext->eglSurface); if(esContext->eglDisplay != EGL_NO_DISPLAY) eglTerminate(esContext->eglDisplay); esContext->eglDisplay = EGL_NO_DISPLAY; esContext->eglContext = EGL_NO_CONTEXT; esContext->eglSurface = EGL_NO_SURFACE; }
// Drawing something
画完后,可以用glReadPixels来读取
GLint size; size = esContext->width * esContext->height * 4; GLubyte *data = (GLubyte*)malloc(size); glPixelStorei(GL_PACK_ALIGNMENT, 4); glReadPixels(0,0,esContext->width,esContext->height,GL_RGB,GL_UNSIGNED_BYTE,data);
可以把读出来的位图流写到一个bmp文件中(bmp在windows下默认是按BGR存的,故需要RGB->BGR)
bmp_write(data, esContext->width, esContext->height, "C:\\SimpleTexture2D");
int bmp_write(unsigned char *image, int xsize, int ysize, char *filename) { unsigned char header[54] = { 0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; long file_size = (long)xsize * (long)ysize * 3 + 54; long width, height; char fname_bmp[128]; FILE *fp; header[2] = (unsigned char)(file_size &0x000000ff); header[3] = (file_size >> 8) & 0x000000ff; header[4] = (file_size >> 16) & 0x000000ff; header[5] = (file_size >> 24) & 0x000000ff; width = xsize; header[18] = width & 0x000000ff; header[19] = (width >> 8) &0x000000ff; header[20] = (width >> 16) &0x000000ff; header[21] = (width >> 24) &0x000000ff; height = ysize; header[22] = height &0x000000ff; header[23] = (height >> 8) &0x000000ff; header[24] = (height >> 16) &0x000000ff; header[25] = (height >> 24) &0x000000ff; sprintf(fname_bmp, "%s.bmp", filename); if (!(fp = fopen(fname_bmp, "wb"))) return -1; // switch the image data from RGB to BGR for(unsigned long imageIdx = 0; imageIdx < file_size; imageIdx+=3) { unsigned char tempRGB = image[imageIdx]; image[imageIdx] = image[imageIdx + 2]; image[imageIdx + 2] = tempRGB; } fwrite(header, sizeof(unsigned char), 54, fp); fwrite(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp); fclose(fp); return 0; }