EGL笔记--未完全看懂 好好理解 2011-12-6

EGL是OpenGL和平台显示相关的部分的封装。http://www.khronos.org/egl/

OpenGL ES的初始化过程如下图所示意:

DISPLAY → CONFIG → SURFACE

                                        ↑

                                    CONTEXT

                                        ↑
                     OpenGL ES Command

 

EGL工作步骤如下:

1。获取显示设备并初始化EGL

    EGLDisplay 是一个系统物理屏幕的通用数据类型。系统可能有多个物理显示设备,EGLDisplay 就是确定用哪个物理设备

  EGLDisplay 操作设备显示的 API 

  EGLDisplay eglGetDisplay (NativeDisplayType display); 其中 display 参数是 native 系统的窗口显示句柄。在windows下为窗口的

   DC,在linux下为打开framebuffer设备返回的设备描述符。如果想得到一个系统默认的Display ,就可以用EGL_DEFAULT_DISPLAY

   参数。如果系统中没有,函数将返回 EGL_NO_DISPLAY 。

   获取后调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor),该函数会进行一些内部初始化工作,

   并传回EGL版本号(major.minor)。

2。 配置EGL
      其实就是配置FrameBuffer的参数,在Windows下对应于PixelFormat,

     用EGLboolean eglChooseConfig(),其中有个参数是以EGL_NONE结束的参数数组,通常以id,value依次存放。

     对于特定平台,可以先用GLboolean eglGetConfigs() 来获得支持的配置,eglGetConfigs()中间两个参数为0时可以得到支持的配

     置总个数。配置有很多属性,可以用eglGetConfigAttrib ()来读取。

    见egl.h
    /* Config attributes */

    #define EGL_BUFFER_SIZE   0x3020
    #define EGL_ALPHA_SIZE   0x3021
   #define EGL_BLUE_SIZE   0x3022
   #define EGL_GREEN_SIZE  

   。。。。

   http://www.khronos.org/egl/ 

3。 构造Surface。
     Surface实际上就是一个FrameBuffer,有多种surface

     要在某个窗口中显示怎用EGLSurface eglCreateWindowSurface() 来创建,只有这种是在物理显示设备上显示的。

     要在内存中以位图保存,则用eglCreatePixmapSurface()来创建,该类型只用于离屏渲染.

     要保存在显存中的帧, 则用eglCreatePbufferSurface()来创建。

    Surface的属性可以用eglSurfaceAttrib()来设置,用和eglQuerySurface()来获取。egl.h中有定义

     /* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
     #define EGL_HEIGHT   0x3056
     #define EGL_WIDTH   0x3057
     #define EGL_LARGEST_PBUFFER  0x3058
     #define EGL_TEXTURE_FORMAT  0x3080
     #define EGL_TEXTURE_TARGET  0x3081
     #define EGL_MIPMAP_TEXTURE  0x3082

      。。。。。。。。

 

   具体见 http://www.khronos.org/egl/ 

 

4。创建Context。
 OpenGL ES的pipeline从程序的角度看就是一个状态机,有当前的颜色、纹理坐标、变换矩阵、绚染模式等一大堆状态,

 这些状态作用于 程序提交的顶点坐标等图元从而形成帧缓冲内的像素。在OpenGL ES的编程接口中,Context就代表这个状态机,

  程序的主要工作就是向Context提供图元、设置状态,偶尔也从Context里获取一些信息。
 用EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)来创建

 一个Context。然后用eglMakeCurrent激活context

 

5. 绘制。
应用程序通过OpenGL ES API进行绘制,一帧完成之后,调用eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)来显示。

如果显示之前处理,则不调用次函数,调glFlush()后调glReadPixels()

例子:

   OpenGLwindows下WGL初始化代码如下:

   #include  <GL/gl.h>

   #include  <GL/egl.h>

   int CheckHardwareSupport(HDC hdc)
  {
     int PixelFormat = GetPixelFormat(hdc);
     PIXELFORMATDESCRIPTOR pfd;

 

     DescribePixelFormat(hdc,PixelFormat,sizeof(PIXELFORMATDESCRIPTOR),&pfd);
     if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))
          return 0; // Software acceleration OpenGL

    else if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && (pfd.dwFlags & PFD_GENERIC_ACCELERATED))
        return 1; // Half hardware acceleration OpenGL (MCD driver)

     else if ( !(pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))
       return 2; // Full hardware acceleration OpenGL
    return -1; // check error
 }

bool windows_opengl_init()
{
 HDC      oglDC = NULL;
 HGLRC     hRC = NULL;
 int      pixelFormat;
 PIXELFORMATDESCRIPTOR pfd;
 int      res;
 char     *opengl_modes[3]={"software","half hardware (MCD driver)","hardware"};

 if(oglAlreadyInit == true) return true;

 oglDC = GetDC (MainWindow->getHWnd());

 memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR));
 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
 pfd.nVersion = 1;
 pfd.dwFlags =  PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
 pfd.iPixelType = PFD_TYPE_RGBA;
 pfd.cColorBits = 24;
 pfd.cDepthBits = 24;
 pfd.cAlphaBits = 8;
 pfd.cStencilBits = 8;
 pfd.iLayerType = PFD_MAIN_PLANE ;

 pixelFormat = ChoosePixelFormat(oglDC, &pfd);


 if (pixelFormat == 0)
  return false;

 if(!SetPixelFormat(oglDC, pixelFormat, &pfd))
  return false;

 

 hRC = wglCreateContext(oglDC);
 if (!hRC)
  return false;

 if(!wglMakeCurrent(oglDC, hRC))
  return false;

 res=CheckHardwareSupport(oglDC);
 if (res>=0&&res<=2) 
   INFO("OpenGL mode: %s/n",opengl_modes[res]); 
  else 
   INFO("OpenGL mode: uknown/n");

 oglAlreadyInit = true;

 return true;
}

OpenGL ES在windows下EGL初始化的例子

bool windows_opengl_init()
{
 EGLDisplay dpy;
 EGLConfig config;
 EGLSurface surface;
 EGLContext context;
 EGLint major;
 EGLint minor;
 EGLint cfg_attr_list[3] = { EGL_BUFFER_SIZE, 16, EGL_NONE};
 EGLBoolean   ret;
 HDC      oglDC = NULL;

 if(oglAlreadyInit == true) return true;

 oglDC = GetDC (MainWindow->getHWnd());
 dpy = eglGetDisplay(oglDC);                //得到DC所在的显示器

 if (dpy==EGL_NO_DISPLAY) {
  return false;
 }
 ret = eglInitialize(dpy, &major, &minor);
 if(ret==EGL_FALSE) {
  return false;
 }
 int num = 0;
 ret = eglChooseConfig(dpy, cfg_attr_list, &config, 1, &num);
 if (  ret== EGL_FALSE || num == 0 )
 {
  return false;
 }
 surface = eglCreateWindowSurface(dpy, config, MainWindow->getHWnd(), 0);
 if ( surface == EGL_NO_SURFACE )
 {
  return false;
 }

 // create context
 // EGLint ctx_attr_list[] = { EGL_NONE };
 context = eglCreateContext(dpy, config, NULL, NULL);

 // active context (make current)
 oglAlreadyInit = eglMakeCurrent(dpy, surface, surface, context);

 return true;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值