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 分四步:
其实跟标准 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_