初始化EGL

OpenGL ES 是一个平台中立的图形库,在它能够工作之前,需要与一个实际的窗 口系统关联起来,这与 OpenGL 是一样的。但不一样的是,这部份工作有标准, 这个标准就是 EGL 。而 OpenGL 时代在不同平台上有不同的机制以关联窗口系 统,在 Windows 上是 wgl,在 X-Window 上是 xgl,在 Apple OS 上是 agl 等。 EGL 的工作方式和部份术语都接近于 xgl。

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

Display → Config → Surface
                        ↑
                      Context
                        ↑
Application → OpenGL Command

1. 获取 Display。

Display 代表显示器,在有些系统上可以有多个显示器,也就会有多个 Display。 获得 Display 要调用

EGLboolean eglGetDisplay(NativeDisplay dpy)

参数一般为 EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的,在 X-Window 下是 XDisplay ID,在 MS Windows 下是 Window DC。

2. 初始化 egl。

初始化 egl 调用

EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)

该函数会进行一些内部初始化工作,并传回 EGL 版本号(major.minor)。

3. 选择Config。

所谓 Config 实际指的是 FrameBuffer 的参数,在 MS Windows 下对应于 PixelFormat,在 X-Window 下对应 Visual。一般用

EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list,
            EGLConfig * config, EGLint config_size, EGLint *num_config)

其中 attr_list 是以 EGL_NONE 结束的参数数组,通常以 id,value 依次存放, 对于个别标识性的属性可以只有 id,没有 value。

另一个办法是用

EGLboolean eglGetConfigs(EGLDisplay dpy, EGLConfig * config, EGLint
config_size, EGLint *num_config)

来获得所有 config。

这两个函数都会返回不多于 config_size 个 Config,结果保存在 config[] 中, 系统的总 Config 个数保存在 num_config 中。可以利用 eglGetConfig() 中间 两个参数为 0 来查询系统支持的 Config 总个数。

Config 有众多的 Attribute,这些 Attribute 决定 FrameBuffer 的格式和能 力,通过

eglGetConfigAttrib ()

来读取,但不能修改。

4. 构造Surface。

Surface 实际上就是一个 FrameBuffer,通过

EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg,
                NativeWindow win, EGLint *cfg_attr)

来创建一个可实际显示的 Surface。系统通常还支持另外两种 Surface: PixmapSurface 和 PBufferSurface,这两种都不是可显示的 Surface, PixmapSurface 是保存在系统内存中的位图,PBuffer 则是保存在显存中的帧。

Surface 也有一些 attribute,基本上都可以故名思意,

EGL_HEIGHT
EGL_WIDTH
EGL_LARGEST_PBUFFER
EGL_TEXTURE_FORMAT
EGL_TEXTURE_TARGET
EGL_MIPMAP_TEXTURE
EGL_MIPMAP_LEVEL

通过 eglSurfaceAttrib() 设置、eglQuerySurface()读取。

eglSurfaceAttrib()

eglQuerySurface()

5. 创建Context。

OpenGL 的 pipeline 从程序的角度看就是一个状态机,有当前的颜色、纹理坐 标、变换矩阵、绚染模式等一大堆状态,这些状态作用于程序提交的顶点坐标等 图元从而形成帧缓冲内的像素。

在 OpenGL 的编程接口中,Context 就代表这个状态机,程序的主要工作就是向 Context 提供图元、设置状态,偶尔也从 Context 里获取一些信息。

EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write,
                EGLSurface read, EGLContext * share_list)

来创建一个 Context。

6. 绘制。

应用程序通过 OpenGL API 进行绘制,一帧完成之后,调用

eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)

来显示。

http://www.linuxgraphics.cn/graphics/opengles_tutorial_base_1.html

初始化 OpenGL ES 分四步:

  • 调用 eglInitialize() 初始化 egl 库,
  • 用 eglChooseConfig() 选择合适的 framebuffer,
  • 调用 eglCreateWindowSurface 创建 EGLSurface,
  • 用 eglCreateContext 创建 RenderContext(RC)。

其实跟标准 OpenGL 的初始化过程很接近(选择 PixelFormat 或者 Visual,再创 建 RC),只是多了一个 Window Surface 的概念。OpenGL 标准是不依赖于窗口 系统的,这提供了很强的平台无关性,但也使得我们在 Windows 下要用 wgl 初 始化,而 X-Window 下就得学会用 xgl,Mac OS X上则是 agl。而手持及嵌入式 市场的平台种类不计其数,单是学习各家手机操作系统的接口就是很大的负担了, 更不用说总有一些有志于支持各种尺寸平台的软件开发者,所以 OpenGL ES 提 供了 Window Surface 的抽象,使得移植工作可以基本局限在重新实现一下建立 窗口的过程。

以下是我的 EGLWrapper 和 EGLConfigWrapper:

用法简单,包含"eglwrapper.h",创建一个 EGLWrapper 实例,调用 init(), 第一个参数是利用系统相关 API 建好的 window id,对 Windows CE 而言就是 HWND 了,程序结束时再 clean()一下就好。

eglwrapper.h 代码如下所示:

  1  //  @ Project : OpenGL ES Wrapper
  2  //  @ File Name : eglwrapper.h
  3  //  @ Date : 2006-7-5
  4  //  @ Author : kongfu.yang
  5  //  @ Company : http://www.play3d.net
  6  //  @ Copyright : 2006-7, Example source license.
         By keep this header comment,
           you may use this source file in your project for non-commicial or commicial purpose.
  7
  8  #ifndef _EGL_WRAPPER_H_
  9  #define _EGL_WRAPPER_H_
 10
 11  #include <gles/gl.h>
 12
 13  #ifdef UNDER_CE
 14  #include <aygshell.h>
 15  #endif
 16  #include "eglConfigWrapper.h"
 17
 18  #include <stdio.h>
 19  #include <math.h>
 20
 21  #pragma warning ( disable : 4244 )
 22
 23  //#define Float2Fixed(fl) (fl)
 24  #define Float2Fixed(fl) ((GLfixed)((fl)*65536.0f))
 25
26  class EGLWrapper
 27  {
 28  private:
 29      EGLDisplay dpy;
 30      EGLConfig config;
 31      EGLSurface surface;
 32      EGLContext context;
 33      EGLint major;
 34      EGLint minor;
 35
 36      NativeWindowType nativeWindow;
 37
 38      bool isFullScreen;
 39
 40  private:
 41      bool initialized;
 42
 43  public:
 44      EGLWrapper()
 45      {
 46          dpy = EGL_NO_DISPLAY;
 47          config = EGL_NONE;
 48          surface = EGL_NO_SURFACE;
 49          context = EGL_NO_CONTEXT;
 50          isFullScreen = false;
 51
 52          initialized = false;
 53      }
 54
 55      bool isInitialized(){ return initialized; }
 56
57      void default3DEnv()
 58      {
 59          glClearColorx(Float2Fixed(0.5), Float2Fixed(0.5), Float2Fixed(0.5), Float2Fixed(1.0));
 60
 61          glShadeModel(GL_SMOOTH);
 62          glEnable(GL_CULL_FACE);
 63          glCullFace(GL_BACK);
 64          glEnable(GL_DEPTH_TEST);
 65          glEnable(GL_TEXTURE_2D);
 66
 67          glMatrixMode(GL_PROJECTION);
 68          glLoadIdentity();
 69          //glFrustumx( Float2Fixed(-10.0f), Float2Fixed(10.0f),
             //            Float2Fixed(-10.0f), Float2Fixed(10.0),
             //            Float2Fixed(0.1f), Float2Fixed(100.0f) );
 70
 71          glMatrixMode(GL_MODELVIEW);
 72          glLoadIdentity();
 73      }
 74
 75      void resize(int width, int height)
 76      {
 77          glViewport( 0, 0, width, height );
 78
 79          glMatrixMode(GL_PROJECTION);
 80          glLoadIdentity();
 81
 82          float top = tan(45.0*3.14159/360.0) * 0.01;
 83          float right = (float)width/(float)height * top;
 84          glFrustumx( Float2Fixed(-right), Float2Fixed(right),
                         Float2Fixed(-top), Float2Fixed(top),
                         Float2Fixed(0.1f), Float2Fixed(1000.0f) );
 85
 86
 87          glMatrixMode(GL_MODELVIEW);
 88          glLoadIdentity();
 89          glTranslatex( 0, 0, Float2Fixed(-60.0f) );
 90      }
 91
 92      void toggleFullScreen()
 93      {
 94  #ifdef UNDER_CE
 95          extern HWND g_hWndMenuBar;
 96
 97          RECT rect;
 98
 99          isFullScreen = !isFullScreen;
100          if ( isFullScreen )
101          {
102              ShowWindow( g_hWndMenuBar, SW_HIDE );
103              SHFullScreen( (HWND) nativeWindow, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON );
104              SetRect(&rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
105              MoveWindow((HWND) nativeWindow, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
106          }else{
107              SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE);
108              MoveWindow((HWND) nativeWindow, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
109              ShowWindow( g_hWndMenuBar, SW_SHOW );
110              SHFullScreen((HWND) nativeWindow, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON);
111          }
112  #endif
113      }
114
115      void setFullScreen()
116      {
117          if ( ! isFullScreen )
118              toggleFullScreen();
119      }
120
121      bool init(NativeWindowType hwnd, int bpp = 16, bool fullscreen=false)
122      {
123          nativeWindow = hwnd;
124
125          if( fullscreen ) toggleFullScreen();
126
127          dpy = eglGetDisplay( (NativeDisplayType) GetDC( (HWND)hwnd ) );
128          if ( ! dpy )
129              return false;
130
131          if ( eglInitialize(dpy, &major, &minor) == EGL_FALSE )
132          {
133              return false;
134          }
135
136          // choose config
137          EGLint cfg_attr_list[] = { EGL_BUFFER_SIZE, bpp, EGL_NONE};
138          int num = 0;
139          if ( eglChooseConfig(dpy, cfg_attr_list, &config, 1, &num) == EGL_FALSE || num == 0 )
140          {
141              return false;
142          }
143
144          // create surface
145          // EGLint sf_attr_list[] = {};
146          surface = eglCreateWindowSurface(dpy, config, hwnd, 0);
147          if ( surface == EGL_NO_SURFACE )
148          {
149              return false;
150          }
151
152          // create context
153          // EGLint ctx_attr_list[] = { EGL_NONE };
154          context = eglCreateContext(dpy, config, NULL, NULL);
155
156          // active context (make current)
157          initialized = makeCurrent();
158
159          default3DEnv();
160
161          glClear( GL_COLOR_BUFFER_BIT );
162
163          return initialized;
164      }
165
166      bool makeCurrent()
167      {
168          EGLBoolean ret = eglMakeCurrent(dpy, surface, surface, context);
169          return ret != EGL_FALSE;
170      }
171
172      bool swapBuffers()
173      {
174          return GL_TRUE == eglSwapBuffers(dpy, surface);
175      }
176
177      int getVersionMajor(){ return major; }
178      int getVersionMinor(){ return minor; }
179
180      void clean()
181      {
182          if ( isFullScreen )
183              toggleFullScreen();
184
185          swapBuffers();
186
187          // deactive context
188          // eglMakeCurrent( dpy, NULL, NULL, NULL );
189          eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ;
190
191          // destroy context
192          if ( context != EGL_NO_CONTEXT )
193              eglDestroyContext( dpy, context );
194
195          // destroy suerface
196          if ( surface != EGL_NO_SURFACE )
197              eglDestroySurface( dpy, surface );
198
199          // terminate display
200          if ( dpy != EGL_NO_DISPLAY )
201              eglTerminate( dpy );
202      }
203
204      // Return attribute values description of all config in the parameter configs
205      void describeConfigs(int num, EGLConfig *configs, ConfigDescription *configDesc)
206      {
207          EGLConfig * ptr = configs;
208          for ( int i = 0; i < num; ++i,++ptr )
209          {
210              EGLConfig * ptr = configs;
211              for ( int i = 0; i < num; ++i,++ptr )
212              {
213                  configDesc[i].describe( dpy, *ptr );
214              }
215          }
216      }
217
218      // Notes: caller MUST response to delete[] the momery pointing by configs allocated inside
219      bool getConfigDescriptions(int & num, ConfigDescription ** configDesc)
220      {
221          bool result = false;
222          if ( eglGetConfigs( dpy, 0, 0, &num ) )
223          {
224              // get configs
225              EGLConfig * configs = new EGLConfig[num]();
226              * configDesc = new ConfigDescription[num]();
227              if ( eglGetConfigs( dpy, configs, num, &num) )
228              {
229                  describeConfigs(num, configs, *configDesc);
230                  result = true;
231              }
232              delete [] configs;
233          }
234
235          return result;
236      }
237
238      void dumpConfig()
239      {
240          int num = 0;
241          if ( eglGetConfigs( dpy, 0, 0, &num ) )
242          {
243              // get configs
244              EGLConfig *configs = (EGLConfig *) malloc( num * sizeof(EGLConfig) );
245              ConfigDescription * configDesc = new ConfigDescription[num]();
246              if ( eglGetConfigs( dpy, configs, num, &num) )
247              {
248                  describeConfigs( num, configs, configDesc);
249
250                  // export config details
251                  FILE * fp = fopen( "config_attribute.csv", "wb" );
252
253                  // print titles
254                  fprintf(fp, "attrName");
255                  EGLConfig * ptr = configs;
256                  for ( int i = 0; i < num; ++i, ++ptr )
257                      fprintf(fp, ",config %d", *ptr);
258                  fprintf(fp, ",explain");
259                  fprintf(fp, "\n");
260
261                  char buf[1024];
262                  // print attributes, one attribute per line, name and value of each config
263                  for ( int j = 0; j < MAX_ATTRIBUTES_OF_CONFIG && configDesc[0].attributes[j].id != 0; ++j )
264                  {
265                      memset( buf, 0,1024);
266                      WideCharToMultiByte( CP_ACP, 0, configDesc[0].attributes[j].name,
                                   wcslen(configDesc[0].attributes[j].name), buf, 1024, NULL, NULL );
267                      fprintf(fp, "\"%s\"", buf);
268                      for ( int i = 0; i < num; ++ i )
269                      {
270                          fprintf( fp, ", 0x%x", configDesc[i].attributes[j].value );
271                      }
272                      memset( buf, 0,1024);
273                      WideCharToMultiByte( CP_ACP, 0, configDesc[0].attributes[j].explain,
                                   wcslen(configDesc[0].attributes[j].explain), buf, 1024, NULL, NULL );
274                      fprintf( fp, ",\"%s\"", buf );
275                      fprintf(fp, "\n");
276                  }
277
278                  fclose(fp);
279              }
280              delete [] configDesc;
281              free( configs );
282          }
283      }
284
285      struct eglErrorString
286      {
287          GLint code;
288          const TCHAR * message;
289      };
290
291      const TCHAR * getErrorString(GLint errorCode)
292      {
293          static eglErrorString errors[] = {
294              { EGL_SUCCESS,
295              TEXT("Function succeeded.") },
296
297              { EGL_NOT_INITIALIZED,
298              TEXT("EGL is not initialized, or could not be initialized, for the specified display.") },
299
300              { EGL_BAD_ACCESS,
301              TEXT("EGL cannot access a requested resource (for example, a context is bound in another thread).") },
302
303              { EGL_BAD_ALLOC,
304              TEXT("EGL failed to allocate resources for the requested operation.") },
305
306              { EGL_BAD_ATTRIBUTE,
307              TEXT("An unrecognized attribute or attribute value was passed in an attribute list.") },
308
309              { EGL_BAD_CONTEXT,
310              TEXT("An EGLContext argument does not name a valid EGLContext.") },
311
312              { EGL_BAD_CONFIG,
313              TEXT("An EGLConfig argument does not name a valid EGLConfig.") },
314
315              { EGL_BAD_CURRENT_SURFACE,
316              TEXT("The current surface of the calling thread is a window, pbuffer, or pixmap that is no longer valid.") },
317
318              { EGL_BAD_DISPLAY,
319              TEXT("An EGLDisplay argument does not name a valid EGLDisplay; or,
                                        EGL is not initialized on the specified EGLDisplay.") },
320
321              { EGL_BAD_SURFACE,
322              TEXT("An EGLSurface argument does not name a valid surface (window, pbuffer, or pixmap)
                                        configured for OpenGL ES rendering.") },
323
324              { EGL_BAD_MATCH,
325              TEXT("Arguments are inconsistent; for example, an otherwise valid context requires buffers
                                        (e.g. depth or stencil) not allocated by an otherwise valid surface.") },
326
327              { EGL_BAD_PARAMETER,
328              TEXT("One or more argument values are invalid.") },
329
330              { EGL_BAD_NATIVE_PIXMAP,
331              TEXT("A NativePixmapType argument does not refer to a valid native pixmap.") },
332
333              { EGL_BAD_NATIVE_WINDOW,
334              TEXT("A NativeWindowType argument does not refer to a valid native window.") },
335
336              { EGL_CONTEXT_LOST,
337              TEXT("A power management event has occurred. The application must destroy all contexts
                        and reinitialise OpenGL ES state and objects to continue rendering, as described in section 2.6.") }
338          };
339
340          for ( int i = 0; i < sizeof(errors); ++i )
341          {
342              if ( errors[i].code == errorCode )
343                  return errors[i].message;
344          }
345
346          return NULL;
347      }
348  };
349
350  #endif // _EGL_WRAPPER_H_


eglConfigWrapper.h 如下所示:

  1  //  @ Project : OpenGL ES Wrapper
  2  //  @ File Name : eglConfigWrapper.h
  3  //  @ Date : 2006-7-5
  4  //  @ Author : kongfu.yang
  5  //  @ Company : http://www.play3d.net
  6  //  @ Copyright : 2006-7, Example source license.
         By keep this header comment,
           you may use this source file in your project for non-commicial or commicial purpose.
  7
  8
  9  #ifndef _EGL_CONFIG_WRAPPER_H_
 10  #define _EGL_CONFIG_WRAPPER_H_
 11
 12  #include <gles/egl.h>
 13
 14  #define MAX_ATTRIBUTES_OF_CONFIG 0x30
 15
 16  struct ConfigAttribute
 17  {
 18          EGLint id;
 19          EGLint value;
 20          TCHAR * name;
 21          TCHAR * explain;
 22  };
 23
 24  class ConfigDescription
 25  {
 26  public:
 27    ConfigAttribute attributes[MAX_ATTRIBUTES_OF_CONFIG];
 28
 29    ConfigDescription()
 30    {
 31        init();
 32    }
 33
 34    void init()
 35    {
 36        int i = 0;
 37
 38        attributes[i].id = EGL_BUFFER_SIZE;
 39        attributes[i].name = TEXT("EGL_BUFFER_SIZE");
 40        attributes[i++].explain = TEXT("color buffer bits, r+g+b+ alpha");
 41
 42        attributes[i].id = EGL_ALPHA_SIZE;
 43        attributes[i].name = TEXT("EGL_ALPHA_SIZE");
 44        attributes[i++].explain = TEXT("bits for alpha");
 45
 46        attributes[i].id = EGL_BLUE_SIZE;
 47        attributes[i].name = TEXT("EGL_BLUE_SIZE");
 48        attributes[i++].explain = TEXT("blue color bits");
 49
 50        attributes[i].id = EGL_GREEN_SIZE;
 51        attributes[i].name = TEXT("EGL_GREEN_SIZE");
 52        attributes[i++].explain = TEXT("green color bits");
 53
 54        attributes[i].id = EGL_RED_SIZE;
 55        attributes[i].name = TEXT("EGL_RED_SIZE");
 56        attributes[i++].explain = TEXT("red color bits");
 57
 58        attributes[i].id = EGL_DEPTH_SIZE;
 59        attributes[i].name = TEXT("EGL_DEPTH_SIZE");
 60        attributes[i++].explain = TEXT("z buffer depth");
 61
 62        attributes[i].id = EGL_STENCIL_SIZE;
 63        attributes[i].name = TEXT("EGL_STENCIL_SIZE");
 64        attributes[i++].explain = TEXT("stancil bits per pixel");
 65
 66        attributes[i].id = EGL_CONFIG_CAVEAT;
 67        attributes[i].name = TEXT("EGL_CONFIG_CAVEAT");
 68        attributes[i++].explain = TEXT("side effect of the config, EGL_NONE(0x3038), EGL_SLOW_CONFIG(0x3050),
                         EGL_NON_COMFORMANT_CONFIG(0x3051,native optimized, but failed to EGL standard comformant test)");
 69
 70        attributes[i].id = EGL_CONFIG_ID;
 71        attributes[i].name = TEXT("EGL_CONFIG_ID");
 72        attributes[i++].explain = TEXT("given config ID");
 73
 74        attributes[i].id = EGL_LEVEL;
 75        attributes[i].name = TEXT("EGL_LEVEL");
 76        attributes[i++].explain = TEXT("0 is defalt, <0 underlay, >0 overlay");
 77
 78        attributes[i].id = EGL_MAX_PBUFFER_PIXELS;
 79        attributes[i].name = TEXT("EGL_MAX_PBUFFER_PIXELS");
 80        attributes[i++].explain = TEXT("maximum pixels in a pbuffer,  maybe not max_width * max_height");
 81
 82        attributes[i].id = EGL_MAX_PBUFFER_HEIGHT;
 83        attributes[i].name = TEXT("EGL_MAX_PBUFFER_HEIGHT");
 84        attributes[i++].explain = TEXT("maximum pixels in y direction");
 85
 86        attributes[i].id = EGL_MAX_PBUFFER_WIDTH;
 87        attributes[i].name = TEXT("EGL_MAX_PBUFFER_WIDTH");
 88        attributes[i++].explain = TEXT("maximum pixels in x direction");
 89
 90        attributes[i].id = EGL_NATIVE_RENDERABLE;
 91        attributes[i].name = TEXT("EGL_NATIVE_RENDERABLE");
 92        attributes[i++].explain = TEXT("native API (GDI) can draw on EGL surface");
 93
 94        attributes[i].id = EGL_NATIVE_VISUAL_ID;
 95        attributes[i].name = TEXT("EGL_NATIVE_VISUAL_ID");
 96        attributes[i++].explain = TEXT("native visual (pixel format) ID");
 97
 98        attributes[i].id = EGL_NATIVE_VISUAL_TYPE;
 99        attributes[i].name = TEXT("EGL_NATIVE_VISUAL_TYPE");
100        attributes[i++].explain = TEXT("native visual type (PIXELFORMAT) ?");
101
102        attributes[i].id = EGL_SAMPLES;
103        attributes[i].name = TEXT("EGL_SAMPLES");
104        attributes[i++].explain = TEXT("sample count required by a multisampling buffer. 0 if none sample buffer");
105
106        attributes[i].id = EGL_SAMPLE_BUFFERS;
107        attributes[i].name = TEXT("EGL_SAMPLE_BUFFERS");
108        attributes[i++].explain = TEXT("number of multisampling buffers");
109
110        attributes[i].id = EGL_SURFACE_TYPE;
111        attributes[i].name = TEXT("EGL_SURFACE_TYPE");
112        attributes[i++].explain = TEXT("supported surface type in config,
                                             EGL_WINDOW_BIT(1)|EGL_PIXMAP_BIT(2)|EGL_PBUFFER_BIT(4)");
113
114        attributes[i].id = EGL_TRANSPARENT_TYPE;
115        attributes[i].name = TEXT("EGL_TRANSPARENT_TYPE");
116        attributes[i++].explain = TEXT("support a special color as transparent. EGL_NONE(0x3038),
                                                                              EGL_TRANSPARENT_RGB(0x3052)");
117
118        attributes[i].id = EGL_TRANSPARENT_BLUE_VALUE;
119        attributes[i].name = TEXT("EGL_TRANSPARENT_BLUE_VALUE");
120        attributes[i++].explain = TEXT("blue component of transparent color");
121
122        attributes[i].id = EGL_TRANSPARENT_GREEN_VALUE;
123        attributes[i].name = TEXT("EGL_TRANSPARENT_GREEN_VALUE");
124        attributes[i++].explain = TEXT("green component of transparent color");
125
126        attributes[i].id = EGL_TRANSPARENT_RED_VALUE;
127        attributes[i].name = TEXT("EGL_TRANSPARENT_RED_VALUE");
128        attributes[i++].explain = TEXT("red component of transparent color");
129
130        // EGL 1.1
131        attributes[i].id = EGL_BIND_TO_TEXTURE_RGB;
132        attributes[i].name = TEXT("EGL_BIND_TO_TEXTURE_RGB");
133        attributes[i++].explain = TEXT("true if bindalble to RGB texture");
134
135        attributes[i].id = EGL_BIND_TO_TEXTURE_RGBA;
136        attributes[i].name = TEXT("EGL_BIND_TO_TEXTURE_RGBA");
137        attributes[i++].explain = TEXT("true if bindalbe to RGBA texture");
138
139        attributes[i].id = EGL_MIN_SWAP_INTERVAL;
140        attributes[i].name = TEXT("EGL_MIN_SWAP_INTERVAL");
141        attributes[i++].explain = TEXT("minimum swap interval");
142
143        attributes[i].id = EGL_MAX_SWAP_INTERVAL;
144        attributes[i].name = TEXT("EGL_MAX_SWAP_INTERVAL");
145        attributes[i++].explain = TEXT("maximum swap interval");
146
147        attributes[i].id = 0;
148        attributes[i].value = 0;
149        attributes[i].name = 0;
150        attributes[i++].explain = 0;
151    }
152
153      bool describe(EGLDisplay dpy, EGLConfig config)
154      {
155          for ( int i = 0; i < MAX_ATTRIBUTES_OF_CONFIG && attributes[i].id != 0; ++i )
156          {
157              eglGetConfigAttrib( dpy, config, attributes[i].id, &attributes[i].value);
158          }
159
160          return true;
161      }
162  };
163
164  #endif //_EGL_CONFIG_WRAPPER_H_


你可能感兴趣的:(初始化EGL)