OpenGL ES系列之基本-2:初始化 GLES

来源:互联网 发布:url编码 java 编辑:程序博客网 时间:2024/05/19 22:55

初始化 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)) 2526  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; } 5657      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  #endif113      }114115      void setFullScreen()116      {117          if ( ! isFullScreen )118              toggleFullScreen();119      }120121      bool init(NativeWindowType hwnd, int bpp = 16, bool fullscreen=false)122      {123          nativeWindow = hwnd;124125          if( fullscreen ) toggleFullScreen();126127          dpy = eglGetDisplay( (NativeDisplayType) GetDC( (HWND)hwnd ) );128          if ( ! dpy )129              return false;130131          if ( eglInitialize(dpy, &major, &minor) == EGL_FALSE )132          {133              return false;134          }135136          // choose config137          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          }143144          // create surface145          // EGLint sf_attr_list[] = {};146          surface = eglCreateWindowSurface(dpy, config, hwnd, 0);147          if ( surface == EGL_NO_SURFACE )148          {149              return false;150          }151152          // create context153          // EGLint ctx_attr_list[] = { EGL_NONE };154          context = eglCreateContext(dpy, config, NULL, NULL);155156          // active context (make current)157          initialized = makeCurrent();158159          default3DEnv();160161          glClear( GL_COLOR_BUFFER_BIT );162163          return initialized;164      }165166      bool makeCurrent()167      {168          EGLBoolean ret = eglMakeCurrent(dpy, surface, surface, context);169          return ret != EGL_FALSE;170      }171172      bool swapBuffers()173      {174          return GL_TRUE == eglSwapBuffers(dpy, surface);175      }176177      int getVersionMajor(){ return major; }178      int getVersionMinor(){ return minor; }179180      void clean()181      {182          if ( isFullScreen )183              toggleFullScreen();184185          swapBuffers();186187          // deactive context188          // eglMakeCurrent( dpy, NULL, NULL, NULL );189          eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ;190191          // destroy context192          if ( context != EGL_NO_CONTEXT )193              eglDestroyContext( dpy, context );194195          // destroy suerface196          if ( surface != EGL_NO_SURFACE )197              eglDestroySurface( dpy, surface );198199          // terminate display200          if ( dpy != EGL_NO_DISPLAY )201              eglTerminate( dpy );202      }203204      // Return attribute values description of all config in the parameter configs205      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      }217218      // Notes: caller MUST response to delete[] the momery pointing by configs allocated inside219      bool getConfigDescriptions(int & num, ConfigDescription ** configDesc)220      {221          bool result = false;222          if ( eglGetConfigs( dpy, 0, 0, &num ) )223          {224              // get configs225              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          }234235          return result;236      }237238      void dumpConfig()239      {240          int num = 0;241          if ( eglGetConfigs( dpy, 0, 0, &num ) )242          {243              // get configs244              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);249250                  // export config details251                  FILE * fp = fopen( "config_attribute.csv", "wb" );252253                  // print titles254                  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");260261                  char buf[1024];262                  // print attributes, one attribute per line, name and value of each config263                  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                  }277278                  fclose(fp);279              }280              delete [] configDesc;281              free( configs );282          }283      }284285      struct eglErrorString286      {287          GLint code;288          const TCHAR * message;289      };290291      const TCHAR * getErrorString(GLint errorCode)292      {293          static eglErrorString errors[] = {294              { EGL_SUCCESS,295              TEXT("Function succeeded.") },296297              { EGL_NOT_INITIALIZED,298              TEXT("EGL is not initialized, or could not be initialized, for the specified display.") },299300              { EGL_BAD_ACCESS,301              TEXT("EGL cannot access a requested resource (for example, a context is bound in another thread).") },302303              { EGL_BAD_ALLOC,304              TEXT("EGL failed to allocate resources for the requested operation.") },305306              { EGL_BAD_ATTRIBUTE,307              TEXT("An unrecognized attribute or attribute value was passed in an attribute list.") },308309              { EGL_BAD_CONTEXT,310              TEXT("An EGLContext argument does not name a valid EGLContext.") },311312              { EGL_BAD_CONFIG,313              TEXT("An EGLConfig argument does not name a valid EGLConfig.") },314315              { EGL_BAD_CURRENT_SURFACE,316              TEXT("The current surface of the calling thread is a window, pbuffer, or pixmap that is no longer valid.") },317318              { EGL_BAD_DISPLAY,319              TEXT("An EGLDisplay argument does not name a valid EGLDisplay; or,                                        EGL is not initialized on the specified EGLDisplay.") },320321              { EGL_BAD_SURFACE,322              TEXT("An EGLSurface argument does not name a valid surface (window, pbuffer, or pixmap)                                        configured for OpenGL ES rendering.") },323324              { 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.") },326327              { EGL_BAD_PARAMETER,328              TEXT("One or more argument values are invalid.") },329330              { EGL_BAD_NATIVE_PIXMAP,331              TEXT("A NativePixmapType argument does not refer to a valid native pixmap.") },332333              { EGL_BAD_NATIVE_WINDOW,334              TEXT("A NativeWindowType argument does not refer to a valid native window.") },335336              { 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          };339340          for ( int i = 0; i < sizeof(errors); ++i )341          {342              if ( errors[i].code == errorCode )343                  return errors[i].message;344          }345346          return NULL;347      }348  };349350  #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) ?");101102        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");105106        attributes[i].id = EGL_SAMPLE_BUFFERS;107        attributes[i].name = TEXT("EGL_SAMPLE_BUFFERS");108        attributes[i++].explain = TEXT("number of multisampling buffers");109110        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)");113114        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)");117118        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");121122        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");125126        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");129130        // EGL 1.1131        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");134135        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");138139        attributes[i].id = EGL_MIN_SWAP_INTERVAL;140        attributes[i].name = TEXT("EGL_MIN_SWAP_INTERVAL");141        attributes[i++].explain = TEXT("minimum swap interval");142143        attributes[i].id = EGL_MAX_SWAP_INTERVAL;144        attributes[i].name = TEXT("EGL_MAX_SWAP_INTERVAL");145        attributes[i++].explain = TEXT("maximum swap interval");146147        attributes[i].id = 0;148        attributes[i].value = 0;149        attributes[i].name = 0;150        attributes[i++].explain = 0;151    }152153      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          }159160          return true;161      }162  };163164  #endif //_EGL_CONFIG_WRAPPER_H_

原创粉丝点击