// @ Project : OpenGL ES Wrapper // @ File Name : eglWrapper.h // @ Date : 2006-7-5 // @ Author : kongfu.yang // @ Company : http://www.play3d.net // @ 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. #ifndef _EGL_WRAPPER_H_ #define _EGL_WRAPPER_H_ #include #ifdef UNDER_CE #include #endif #include "eglConfigWrapper.h" #include #include #pragma warning ( disable : 4244 ) //#define Float2Fixed(fl) (fl) #define Float2Fixed(fl) ((GLfixed)((fl)*65536.0f)) class EGLWrapper { private: EGLDisplay dpy; EGLConfig config; EGLSurface surface; EGLContext context; EGLint major; EGLint minor; NativeWindowType nativeWindow; bool isFullScreen; private: bool initialized; public: EGLWrapper() { dpy = EGL_NO_DISPLAY; config = EGL_NONE; surface = EGL_NO_SURFACE; context = EGL_NO_CONTEXT; isFullScreen = false; initialized = false; } bool isInitialized(){ return initialized; } void default3DEnv() { glClearColorx(Float2Fixed(0.5), Float2Fixed(0.5), Float2Fixed(0.5), Float2Fixed(1.0)); glShadeModel(GL_SMOOTH); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //glFrustumx( Float2Fixed(-10.0f), Float2Fixed(10.0f), Float2Fixed(-10.0f), Float2Fixed(10.0), Float2Fixed(0.1f), Float2Fixed(100.0f) ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void resize(int width, int height) { glViewport( 0, 0, width, height ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float top = tan(45.0*3.14159/360.0) * 0.01; float right = (float)width/(float)height * top; glFrustumx( Float2Fixed(-right), Float2Fixed(right), Float2Fixed(-top), Float2Fixed(top), Float2Fixed(0.1f), Float2Fixed(1000.0f) ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatex( 0, 0, Float2Fixed(-60.0f) ); // fixpoint : hi 16 bits are integer part, low 16 bits are fragmental part. } void toggleFullScreen() { #ifdef UNDER_CE extern HWND g_hWndMenuBar; RECT rect; isFullScreen = !isFullScreen; if ( isFullScreen ) { ShowWindow( g_hWndMenuBar, SW_HIDE ); SHFullScreen( (HWND) nativeWindow, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON ); SetRect(&rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); MoveWindow((HWND) nativeWindow, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); }else{ SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE); MoveWindow((HWND) nativeWindow, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); ShowWindow( g_hWndMenuBar, SW_SHOW ); SHFullScreen((HWND) nativeWindow, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON); } #endif } void setFullScreen() { if ( ! isFullScreen ) toggleFullScreen(); } bool init(NativeWindowType hwnd, int bpp = 16, bool fullscreen=false) { nativeWindow = hwnd; if( fullscreen ) toggleFullScreen(); dpy = eglGetDisplay( (NativeDisplayType) GetDC( (HWND)hwnd ) ); if ( ! dpy ) return false; if ( eglInitialize(dpy, &major, &minor) == EGL_FALSE ) { return false; } // choose config EGLint cfg_attr_list[] = { EGL_BUFFER_SIZE, bpp, EGL_NONE}; int num = 0; if ( eglChooseConfig(dpy, cfg_attr_list, &config, 1, &num) == EGL_FALSE || num == 0 ) { return false; } // create surface // EGLint sf_attr_list[] = {}; surface = eglCreateWindowSurface(dpy, config, hwnd, 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) initialized = makeCurrent(); default3DEnv(); glClear( GL_COLOR_BUFFER_BIT ); return initialized; } bool makeCurrent() { EGLBoolean ret = eglMakeCurrent(dpy, surface, surface, context); return ret != EGL_FALSE; } bool swapBuffers() { return GL_TRUE == eglSwapBuffers(dpy, surface); } int getVersionMajor(){ return major; } int getVersionMinor(){ return minor; } void clean() { if ( isFullScreen ) toggleFullScreen(); swapBuffers(); // deactive context // eglMakeCurrent( dpy, NULL, NULL, NULL ); eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ; // destroy context if ( context != EGL_NO_CONTEXT ) eglDestroyContext( dpy, context ); // destroy suerface if ( surface != EGL_NO_SURFACE ) eglDestroySurface( dpy, surface ); // terminate display if ( dpy != EGL_NO_DISPLAY ) eglTerminate( dpy ); } // Return attribute values description of all config in the parameter configs void describeConfigs(int num, EGLConfig *configs, ConfigDescription *configDesc) { EGLConfig * ptr = configs; for ( int i = 0; i < num; ++i,++ptr ) { EGLConfig * ptr = configs; for ( int i = 0; i < num; ++i,++ptr ) { configDesc[i].describe( dpy, *ptr ); } } } // Notes: caller MUST response to delete[] the momery pointing by configs allocated inside bool getConfigDescriptions(int & num, ConfigDescription ** configDesc) { bool result = false; if ( eglGetConfigs( dpy, 0, 0, &num ) ) { // get configs EGLConfig * configs = new EGLConfig[num](); * configDesc = new ConfigDescription[num](); if ( eglGetConfigs( dpy, configs, num, &num) ) { describeConfigs(num, configs, *configDesc); result = true; } delete [] configs; } return result; } void dumpConfig() { int num = 0; if ( eglGetConfigs( dpy, 0, 0, &num ) ) { // get configs EGLConfig *configs = (EGLConfig *) malloc( num * sizeof(EGLConfig) ); ConfigDescription * configDesc = new ConfigDescription[num](); if ( eglGetConfigs( dpy, configs, num, &num) ) { describeConfigs( num, configs, configDesc); // export config details FILE * fp = fopen( "config_attribute.csv", "wb" ); // print titles fprintf(fp, "attrName"); EGLConfig * ptr = configs; for ( int i = 0; i < num; ++i, ++ptr ) fprintf(fp, ",config %d", *ptr); fprintf(fp, ",explain"); fprintf(fp, "\n"); char buf[1024]; // print attributes, one attribute per line, name and value of each config for ( int j = 0; j < MAX_ATTRIBUTES_OF_CONFIG && configDesc[0].attributes[j].id != 0; ++j ) { memset( buf, 0,1024); WideCharToMultiByte( CP_ACP, 0, configDesc[0].attributes[j].name, wcslen(configDesc[0].attributes[j].name), buf, 1024, NULL, NULL ); fprintf(fp, "\"%s\"", buf); for ( int i = 0; i < num; ++ i ) { fprintf( fp, ", 0x%x", configDesc[i].attributes[j].value ); } memset( buf, 0,1024); WideCharToMultiByte( CP_ACP, 0, configDesc[0].attributes[j].explain, wcslen(configDesc[0].attributes[j].explain), buf, 1024, NULL, NULL ); fprintf( fp, ",\"%s\"", buf ); fprintf(fp, "\n"); } fclose(fp); } delete [] configDesc; free( configs ); } } struct eglErrorString { GLint code; const TCHAR * message; }; const TCHAR * getErrorString(GLint errorCode) { static eglErrorString errors[] = { { EGL_SUCCESS, TEXT("Function succeeded.") }, { EGL_NOT_INITIALIZED, TEXT("EGL is not initialized, or could not be initialized, for the specified display.") }, { EGL_BAD_ACCESS, TEXT("EGL cannot access a requested resource (for example, a context is bound in another thread).") }, { EGL_BAD_ALLOC, TEXT("EGL failed to allocate resources for the requested operation.") }, { EGL_BAD_ATTRIBUTE, TEXT("An unrecognized attribute or attribute value was passed in an attribute list.") }, { EGL_BAD_CONTEXT, TEXT("An EGLContext argument does not name a valid EGLContext.") }, { EGL_BAD_CONFIG, TEXT("An EGLConfig argument does not name a valid EGLConfig.") }, { EGL_BAD_CURRENT_SURFACE, TEXT("The current surface of the calling thread is a window, pbuffer, or pixmap that is no longer valid.") }, { EGL_BAD_DISPLAY, TEXT("An EGLDisplay argument does not name a valid EGLDisplay; or, EGL is not initialized on the specified EGLDisplay.") }, { EGL_BAD_SURFACE, TEXT("An EGLSurface argument does not name a valid surface (window, pbuffer, or pixmap) configured for OpenGL ES rendering.") }, { EGL_BAD_MATCH, TEXT("Arguments are inconsistent; for example, an otherwise valid context requires buffers (e.g. depth or stencil) not allocated by an otherwise valid surface.") }, { EGL_BAD_PARAMETER, TEXT("One or more argument values are invalid.") }, { EGL_BAD_NATIVE_PIXMAP, TEXT("A NativePixmapType argument does not refer to a valid native pixmap.") }, { EGL_BAD_NATIVE_WINDOW, TEXT("A NativeWindowType argument does not refer to a valid native window.") }, { EGL_CONTEXT_LOST, 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.") } }; for ( int i = 0; i < sizeof(errors); ++i ) { if ( errors[i].code == errorCode ) return errors[i].message; } return NULL; } }; #endif // _EGL_WRAPPER_H_