zoukankan      html  css  js  c++  java
  • OpenGL ES2 的OffScreen实现

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

      

  • 相关阅读:
    Android数据存储之SQLCipher数据库加密
    Android数据加密之Aes加密
    Android自定义控件之自定义组合控件
    Android自定义控件之自定义属性
    Android自定义控件之基本原理
    Java设计模式之代理模式(Proxy)
    Android注解使用之使用Support Annotations注解优化代码
    Java学习之注解Annotation实现原理
    Android数据存储之GreenDao 3.0 详解
    Android性能优化之App应用启动分析与优化
  • 原文地址:https://www.cnblogs.com/leon032/p/2729590.html
Copyright © 2011-2022 走看看