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

      

  • 相关阅读:
    RTMP、RTSP/OVIF、GB/T28181视频流媒体服务器的视频传输方式有哪几种?
    RTSP/ONVIF互联网直播服务器录像回看接口调用时查询到超出指定时间段录像文件
    RTSP/onvif网络摄像头直播时网页流媒体视频服务器可以查看所有在线视频流吗?
    安防网络摄像头互联网直播录像设置永久储存却只能播放一半问题解决
    海康大华网络摄像头视频直播流媒体服务器视频广场显示暂无快照的问题解决
    国标GB28181摄像头直播视频流媒体服务器获取视频流失败问题分析
    安防网络摄像头互联网直播流媒体服务器EasyNVR云终端断电重启后无法登录问题解决
    视频管理平台连接EasyNVR在公网IP下通过域名访问报错“请求服务不存在或停止”问题的解决
    安防/互联网直播点播系统在特种车用车安全行车辅助中的应用
    目前视频监控领域高清化的关键技术有哪些?
  • 原文地址:https://www.cnblogs.com/leon032/p/2729590.html
Copyright © 2020-2023  润新知