/*======================================================== * Init base EGL * ======================================================*/ int EGL_Open( void ) { // use EGL to initialise GLES printf( "EGL Open display\n" ); g_x11Display = XOpenDisplay(NULL); if (!g_x11Display) { fprintf(stderr, "ERROR: unable to get display!\n"); return 0; } printf( "EGL Get display\n" ); g_eglDisplay = eglGetDisplay((EGLNativeDisplayType)g_x11Display); if (g_eglDisplay == EGL_NO_DISPLAY) { TestEGLError(); fprintf(stderr, "ERROR: Unable to initialise EGL display.\n"); return 0; } // Initialise egl printf( "EGL Init\n" ); if (!eglInitialize(g_eglDisplay, NULL, NULL)) { TestEGLError(); fprintf(stderr, "ERROR: Unable to initialise EGL display.\n"); return 0; } return 1; }
/*!***************************************************************************************************************************************** @Function SetupEGLContext @Input eglDisplay The EGLDisplay used by the application @Input eglConfig An EGLConfig chosen by the application @Input eglSurface The EGLSurface created from the native window. @Output eglContext The EGLContext created by this function @Input nativeWindow A native window, used to display error messages @Return Whether the function succeeds or not. @Description Sets up the EGLContext, creating it and then installing it to the current thread. *******************************************************************************************************************************************/ bool SetupEGLContext( EGLDisplay eglDisplay, EGLConfig eglConfig, EGLSurface eglSurface, EGLContext& eglContext ) { /* Create a context. EGL has to create what is known as a context for OpenGL ES. The concept of a context is OpenGL ES's way of encapsulating any resources and state. What appear to be "global" functions in OpenGL actually only operate on the current context. A context is required for any operations in OpenGL ES. Similar to an EGLConfig, a context takes in a list of attributes specifying some of its capabilities. However in most cases this is limited to just requiring the version of the OpenGL ES context required - In this case, OpenGL ES 1.x is required which is the default, so there's no need to specify anything. */ // Create the context with the context attributes supplied eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL); if (!TestEGLError("eglCreateContext")) { return false; } /* Bind the context to the current thread. Due to the way OpenGL uses global functions, contexts need to be made current so that any function call can operate on the correct context. Specifically, make current will bind the context to the thread it's called from, and unbind it from any others. To use multiple contexts at the same time, users should use multiple threads and synchronise between them. */ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError("eglMakeCurrent")) { return false; } return true; }
/*=========================================================== Initialise OpenGL settings ===========================================================*/ int ConfigureEGL(EGLConfig config) { // Cleanup in case of a reset if( g_eglSurface || g_eglContext || g_eglDisplay ) { eglMakeCurrent(g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT); eglDestroyContext(g_eglDisplay, g_eglContext); eglDestroySurface(g_eglDisplay, g_eglSurface); } // Bind GLES and create the context printf( "EGL Bind\n" ); eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError() ) { return 0; } printf( "EGL Create Context\n" ); g_eglContext = eglCreateContext(g_eglDisplay, config, NULL, NULL); if (g_eglContext == EGL_NO_CONTEXT) { TestEGLError(); fprintf(stderr, "ERROR: Unable to create GLES context!\n"); return 0; } // Get the SDL window handle SDL_SysWMinfo sysInfo; //Will hold our Window information SDL_VERSION(&sysInfo.version); //Set SDL version if(SDL_GetWMInfo(&sysInfo) <= 0) { TestEGLError(); fprintf( stderr, "ERROR: Unable to get window handle\n"); return 0; } printf( "EGL Create window surface\n" ); g_eglSurface = eglCreateWindowSurface(g_eglDisplay, config, (EGLNativeWindowType)sysInfo.info.x11.window, 0); if ( g_eglSurface == EGL_NO_SURFACE) { TestEGLError(); fprintf(stderr, "ERROR: Unable to create EGL surface!\n"); return 0; } printf( "EGL Make Current\n" ); if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) == EGL_FALSE) { TestEGLError(); fprintf(stderr, "ERROR: Unable to make GLES context current\n"); return 0; } printf( "EGL Done\n" ); return 1; }
/*!**************************************************************************** @Function main @Return int result code to OS @Description Main function of the program ******************************************************************************/ int main() { initEGL(); Init(); //create_texture(); for(;;) { glClear(GL_COLOR_BUFFER_BIT); /* Clears the color buffer. glClear() can also be used to clear the depth or stencil buffer (GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT) */ glClearColor(0.0, 0.5, 0.5, 1.0); glClear(GL_DEPTH_BUFFER_BIT); if (!TestEGLError("glClear")) { goto cleanup; } glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColorMask(false, true, true, true); Light(0); Render(0); glClear( GL_DEPTH_BUFFER_BIT) ; glColorMask(true, false, false, true); Light(1); Render(1); glColorMask( true, true, true, true); XRotate+=0.5; /* Swap Buffers. Brings to the native display the current render surface. */ eglSwapBuffers(eglDisplay, eglSurface); if (!TestEGLError("eglSwapBuffers")) { goto cleanup; } } /* Step 8 - Terminate OpenGL ES and destroy the window (if present). eglTerminate takes care of destroying any context or surface created */ cleanup: // Delete the VBO as it is no longer needed glDeleteBuffers(1, &ui32Vbo); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ; eglTerminate(eglDisplay); return 0; }
void draw_triangle() { /* Draw a triangle */ // Enable vertex arrays glEnableClientState(GL_VERTEX_ARRAY); /* Set the vertex pointer. */ glVertexPointer(3, GL_FLOAT, sizeof(float) * 7, 0); // Set color data in the same way glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4,GL_FLOAT,sizeof(float) * 7, (GLvoid*) (sizeof(float) * 3) /*The color starts after the 3 position values (x,y,z)*/); /* Draws a non-indexed triangle array from the pointers previously given. */ glDrawArrays(GL_TRIANGLES, 0, 3); if (!TestEGLError("glDrawArrays")) { goto cleanup; } cleanup: return; }
/*!***************************************************************************************************************************************** @Function CreateEGLSurface @Input nativeWindow A native window that's been created @Input eglDisplay The EGLDisplay used by the application @Input eglConfig An EGLConfig chosen by the application @Output eglSurface The EGLSurface created from the native window. @Return Whether the function succeeds or not. @Description Creates an EGLSurface from a native window *******************************************************************************************************************************************/ bool CreateEGLSurface( HWND nativeWindow, EGLDisplay eglDisplay, EGLConfig eglConfig, EGLSurface& eglSurface) { /* Create an EGLSurface for rendering. Using a native window created earlier and a suitable eglConfig, a surface is created that can be used to render OpenGL ES calls to. There are three main surface types in EGL, which can all be used in the same way once created but work slightly differently: - Window Surfaces - These are created from a native window and are drawn to the screen. - Pixmap Surfaces - These are created from a native windowing system as well, but are offscreen and are not displayed to the user. - PBuffer Surfaces - These are created directly within EGL, and like Pixmap Surfaces are offscreen and thus not displayed. The offscreen surfaces are useful for non-rendering contexts and in certain other scenarios, but for most applications the main surface used will be a window surface as performed below. */ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, nativeWindow, NULL); if(eglSurface == EGL_NO_SURFACE) { eglGetError(); // Clear error eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, NULL, NULL); } // Check for any EGL Errors if (!TestEGLError(nativeWindow, "eglCreateWindowSurface")) { return false; } return true; }
/*!***************************************************************************************************************************************** @Function SetupEGLContext @Input eglDisplay The EGLDisplay used by the application @Input eglConfig An EGLConfig chosen by the application @Input eglSurface The EGLSurface created from the native window. @Output eglContext The EGLContext created by this function @Return Whether the function succeeds or not. @Description Sets up the EGLContext, creating it and then installing it to the current thread. *******************************************************************************************************************************************/ bool SetupEGLContext( EGLDisplay eglDisplay, EGLConfig eglConfig, EGLSurface eglSurface, EGLContext& eglContext ) { /* Make OpenGL ES the current API. EGL needs a way to know that any subsequent EGL calls are going to be affecting OpenGL ES, rather than any other API (such as OpenVG). */ eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) { return false; } /* Create a context. EGL has to create what is known as a context for OpenGL ES. The concept of a context is OpenGL ES's way of encapsulating any resources and state. What appear to be "global" functions in OpenGL actually only operate on the current context. A context is required for any operations in OpenGL ES. Similar to an EGLConfig, a context takes in a list of attributes specifying some of its capabilities. However in most cases this is limited to just requiring the version of the OpenGL ES context required - In this case, OpenGL ES 2.0. */ EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; // Create the context with the context attributes supplied eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, contextAttributes); if (!TestEGLError("eglCreateContext")) { return false; } /* Bind the context to the current thread. Due to the way OpenGL uses global functions, contexts need to be made current so that any function call can operate on the correct context. Specifically, make current will bind the context to the thread it's called from, and unbind it from any others. To use multiple contexts at the same time, users should use multiple threads and synchronise between them. */ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError("eglMakeCurrent")) { return false; } return true; }
/*!***************************************************************************************************************************************** @Function CreateEGLSurface @Input eglDisplay The EGLDisplay used by the application @Input eglConfig An EGLConfig chosen by the application @Output eglSurface The EGLSurface created @Return Whether the function succeeds or not. @Description Creates an EGLSurface for the screen *******************************************************************************************************************************************/ bool CreateEGLSurface( EGLDisplay eglDisplay, EGLConfig eglConfig, EGLSurface& eglSurface) { /* Create an EGLSurface for rendering. Using a native window created earlier and a suitable eglConfig, a surface is created that can be used to render OpenGL ES calls to. There are three main surface types in EGL, which can all be used in the same way once created but work slightly differently: - Window Surfaces - These are created from a native window and are drawn to the screen. - Pixmap Surfaces - These are created from a native windowing system as well, but are offscreen and are not displayed to the user. - PBuffer Surfaces - These are created directly within EGL, and like Pixmap Surfaces are offscreen and thus not displayed. The offscreen surfaces are useful for non-rendering contexts and in certain other scenarios, but for most applications the main surface used will be a window surface as performed below. For NULL window systems, there are no actual windows, so NULL is passed to this function. */ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)0, NULL); if (!TestEGLError("eglCreateWindowSurface")) { return false; } return true; }
/*======================================================= * Detect available video resolutions =======================================================*/ int FindAppropriateEGLConfigs( void ) { static const EGLint s_configAttribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE }; if (eglChooseConfig(g_eglDisplay, s_configAttribs, g_allConfigs, g_totalConfigsIn, &g_totalConfigsFound) != EGL_TRUE || g_totalConfigsFound == 0) { TestEGLError(); fprintf(stderr, "ERROR: Unable to query for available configs.\n"); return 0; } fprintf(stderr, "Found %d available configs\n", g_totalConfigsFound); return 1; }
/*=========================================================== Setup EGL context and surface ===========================================================*/ int EGL_Init( void ) { FindAppropriateEGLConfigs(); int configIndex = 0; printf( "Config %d\n", configIndex ); if (!ConfigureEGL(g_allConfigs[configIndex])) { TestEGLError(); fprintf(stderr, "ERROR: Unable to initialise EGL. See previous error.\n"); return 1; } /* Pandora VSync */ fbdev = open ("/dev/fb0", O_RDONLY /* O_RDWR */ ); if ( fbdev < 0 ) { fprintf ( stderr, "Couldn't open /dev/fb0 for vsync\n" ); } /* Pandora VSync End */ return 0; }
int ogl_init_window(int x, int y) { int use_x,use_y,use_bpp; Uint32 use_flags; #ifdef OGLES SDL_SysWMinfo info; Window x11Window = 0; Display* x11Display = 0; EGLint ver_maj, ver_min; EGLint configAttribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE, EGL_NONE }; // explicitely request an OpenGL ES 1.x context EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE, EGL_NONE }; // explicitely request a doublebuffering window EGLint winAttribs[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE, EGL_NONE }; int iConfigs; #endif // OGLES if (gl_initialized) ogl_smash_texture_list_internal();//if we are or were fullscreen, changing vid mode will invalidate current textures SDL_WM_SetCaption(DESCENT_VERSION, "Descent II"); SDL_WM_SetIcon( SDL_LoadBMP( "d2x-rebirth.bmp" ), NULL ); use_x=x; use_y=y; use_bpp=GameArg.DbgBpp; use_flags=sdl_video_flags; if (sdl_no_modeswitch) { const SDL_VideoInfo *vinfo=SDL_GetVideoInfo(); if (vinfo) { use_x=vinfo->current_w; use_y=vinfo->current_h; use_bpp=vinfo->vfmt->BitsPerPixel; use_flags=SDL_SWSURFACE | SDL_ANYFORMAT; } else { con_printf(CON_URGENT, "Could not query video info\n"); } } if (!SDL_SetVideoMode(use_x, use_y, use_bpp, use_flags)) { #ifdef RPI con_printf(CON_URGENT, "Could not set %dx%dx%d opengl video mode: %s\n (Ignored for RPI)", x, y, GameArg.DbgBpp, SDL_GetError()); #else Error("Could not set %dx%dx%d opengl video mode: %s\n", x, y, GameArg.DbgBpp, SDL_GetError()); #endif } #ifdef OGLES #ifndef RPI // NOTE: on the RPi, the EGL stuff is not connected to the X11 window, // so there is no need to destroy and recreate this ogles_destroy(); #endif SDL_VERSION(&info.version); if (SDL_GetWMInfo(&info) > 0) { if (info.subsystem == SDL_SYSWM_X11) { x11Display = info.info.x11.display; x11Window = info.info.x11.window; con_printf (CON_DEBUG, "Display: %p, Window: %i ===\n", (void*)x11Display, (int)x11Window); } } if (eglDisplay == EGL_NO_DISPLAY) { #ifdef RPI eglDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); #else eglDisplay = eglGetDisplay((EGLNativeDisplayType)x11Display); #endif if (eglDisplay == EGL_NO_DISPLAY) { con_printf(CON_URGENT, "EGL: Error querying EGL Display\n"); } if (!eglInitialize(eglDisplay, &ver_maj, &ver_min)) { con_printf(CON_URGENT, "EGL: Error initializing EGL\n"); } else { con_printf(CON_DEBUG, "EGL: Initialized, version: major %i minor %i\n", ver_maj, ver_min); } } #ifdef RPI if (rpi_setup_element(x,y,sdl_video_flags,1)) { Error("RPi: Could not set up a %dx%d element\n", x, y); } #endif if (eglSurface == EGL_NO_SURFACE) { if (!eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { con_printf(CON_URGENT, "EGL: Error choosing config\n"); } else { con_printf(CON_DEBUG, "EGL: config chosen\n"); } #ifdef RPI eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)&nativewindow, winAttribs); #else eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)x11Window, winAttribs); #endif if ((!TestEGLError("eglCreateWindowSurface")) || eglSurface == EGL_NO_SURFACE) { con_printf(CON_URGENT, "EGL: Error creating window surface\n"); } else { con_printf(CON_DEBUG, "EGL: Created window surface\n"); } } if (eglContext == EGL_NO_CONTEXT) { eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs); if ((!TestEGLError("eglCreateContext")) || eglContext == EGL_NO_CONTEXT) { con_printf(CON_URGENT, "EGL: Error creating context\n"); } else { con_printf(CON_DEBUG, "EGL: Created context\n"); } } eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError("eglMakeCurrent")) { con_printf(CON_URGENT, "EGL: Error making current\n"); } else { con_printf(CON_DEBUG, "EGL: made context current\n"); } #endif linedotscale = ((x/640<y/480?x/640:y/480)<1?1:(x/640<y/480?x/640:y/480)); gl_initialized=1; return 0; }
void initEGL() { /* Step 1 - Get the default display. */ eglDisplay = eglGetDisplay((NativeDisplayType)0); /* Step 2 - Initialize EGL. */ EGLint iMajorVersion, iMinorVersion; if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) { printf("Error: eglInitialize() failed.\n"); goto cleanup; } /* Step 3 - Specify the required configuration attributes. */ EGLint pi32ConfigAttribs[3]; pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; pi32ConfigAttribs[1] = EGL_WINDOW_BIT; pi32ConfigAttribs[2] = EGL_NONE; /* Step 4 - Find a config that matches all requirements. */ EGLint iConfigs; if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { printf("Error: eglChooseConfig() failed.\n"); goto cleanup; } /* Step 5 - Create a surface to draw to. */ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)0, NULL); if (!TestEGLError("eglCreateWindowSurface")) { goto cleanup; } /* Step 6 - Create a context. */ eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL); if (!TestEGLError("eglCreateContext")) { goto cleanup; } /* Step 7 - Bind the context to the current thread and use our */ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError("eglMakeCurrent")) { goto cleanup; } cleanup: return; }
void maemoGLinit() { printf ("GL init\n"); EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; #if defined(USE_X11) enum { _NET_WM_STATE_REMOVE =0, _NET_WM_STATE_ADD = 1, _NET_WM_STATE_TOGGLE =2 }; Window sRootWindow; XSetWindowAttributes sWA; unsigned int ui32Mask; int i32Depth; #endif EGLint *attribList = NULL; if (use_fsaa) { printf( "GLES: Using Full Scene Antialiasing\n" ); attribList = attrib_list_fsaa; } else { attribList = attrib_list; } #if defined(USE_X11) pandora_driver_mode = MODE_X11; // TODO make configurable #else pandora_driver_mode = MODE_RAW; // TODO make configurable #endif switch(pandora_driver_mode) { #if defined(USE_X11) case MODE_X11: // Initializes the display and screen x11Display = XOpenDisplay( ":0" ); if (!x11Display) { printf("GLES Error: Unable to open X display\n"); } x11Screen = XDefaultScreen( x11Display ); // Gets the display parameters so we can pass the same parameters to the window to be created. sRootWindow = RootWindow(x11Display, x11Screen); i32Depth = DefaultDepth(x11Display, x11Screen); px11Visual = &x11Visual; XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual); if (!px11Visual) { printf("GLES Error: Unable to acquire visual\n"); } // Colormap of the specified visual type for the display. x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone ); sWA.colormap = x11Colormap; // List of events to be handled by the application. Add to these for handling other events. sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; // Display capabilities list. ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; // Creates the X11 window x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY, 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA); // Make the window viewable and flush the output buffer. XMapWindow(x11Display, x11Window); XFlush(x11Display); // Make the window fullscreen unsigned char fullScreen = 1; Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False); XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.window = x11Window; xev.xclient.message_type = wmState; xev.xclient.format = 32; xev.xclient.data.l[0] = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE); xev.xclient.data.l[1] = wmFullScreen; xev.xclient.data.l[2] = 0; XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); display = eglGetDisplay( (EGLNativeDisplayType)x11Display ); break; #endif case MODE_RAW: default: display = eglGetDisplay( (EGLNativeDisplayType)0 ); break; } if( display == EGL_NO_DISPLAY ) { printf( "GLES EGL Error: GL No Display\n" ); } if( !eglInitialize( display, &majorVersion, &minorVersion ) ) { printf( "GLES EGL Error: eglInitialize failed\n" ); } if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) ) { printf( "GLES EGL Error: eglChooseConfig failed\n" ); } context = eglCreateContext( display, config, NULL, NULL ); if( context==0 ) { printf( "GLES EGL Error: eglCreateContext failed\n" ); } switch(pandora_driver_mode) { #if defined(USE_X11) case MODE_X11: surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)x11Window, NULL ); break; #endif case MODE_RAW: default: surface = eglCreateWindowSurface( display, config, (EGLNativeDisplayType)0, NULL ); break; } eglMakeCurrent( display, surface, surface, context ); if (!TestEGLError("eglMakeCurrent")) printf("error eglMakeCurrent"); else printf("GLES Window Opened\n"); }
/*!***************************************************************************************************************************************** @Function RenderScene @Input eglDisplay The EGLDisplay used by the application @Input eglSurface The EGLSurface created from the native window. @Input nativeDisplay The native display used by the application @Return Whether the function succeeds or not. @Description Renders the scene to the framebuffer. Usually called within a loop. *******************************************************************************************************************************************/ bool RenderScene( EGLDisplay eglDisplay, EGLSurface eglSurface, Display* nativeDisplay ) { /* Set the clear color At the start of a frame, generally you clear the image to tell OpenGL ES that you're done with whatever was there before and want to draw a new frame. In order to do that however, OpenGL ES needs to know what colour to set in the image's place. glClearColor sets this value as 4 floating point values between 0.0 and 1.x, as the Red, Green, Blue and Alpha channels. Each value represents the intensity of the particular channel, with all 0.0 being transparent black, and all 1.x being opaque white. Subsequent calls to glClear with the colour bit will clear the frame buffer to this value. The functions glClearDepth and glClearStencil allow an application to do the same with depth and stencil values respectively. */ glClearColor(0.6f, 0.8f, 1.0f, 1.0f); /* Clears the color buffer. glClear is used here with the Colour Buffer to clear the colour. It can also be used to clear the depth or stencil buffer using GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT, respectively. */ glClear(GL_COLOR_BUFFER_BIT); // Enable the vertex array glEnableClientState(GL_VERTEX_ARRAY); // Sets the vertex data to this attribute index, with the number of floats in each position glVertexPointer(3, GL_FLOAT, 3*sizeof(GLfloat), (GLvoid*)0); if (!TestGLError("glVertexAttribPointer")) { return false; } // Set a color to render glColor4f(1.0f, 1.0f, 0.66f, 1.0f); /* Draw the triangle glDrawArrays is a draw call, and executes the shader program using the vertices and other state set by the user. Draw calls are the functions which tell OpenGL ES when to actually draw something to the framebuffer given the current state. glDrawArrays causes the vertices to be submitted sequentially from the position given by the "first" argument until it has processed "count" vertices. Other draw calls exist, notably glDrawElements which also accepts index data to allow the user to specify that some vertices are accessed multiple times, without copying the vertex multiple times. Others include versions of the above that allow the user to draw the same object multiple times with slightly different data, and a version of glDrawElements which allows a user to restrict the actual indices accessed. */ glDrawArrays(GL_TRIANGLES, 0, 3); if (!TestGLError("glDrawArrays")) { return false; } /* Present the display data to the screen. When rendering to a Window surface, OpenGL ES is double buffered. This means that OpenGL ES renders directly to one frame buffer, known as the back buffer, whilst the display reads from another - the front buffer. eglSwapBuffers signals to the windowing system that OpenGL ES 1.x has finished rendering a scene, and that the display should now draw to the screen from the new data. At the same time, the front buffer is made available for OpenGL ES 1.x to start rendering to. In effect, this call swaps the front and back buffers. */ if (!eglSwapBuffers(eglDisplay, eglSurface) ) { TestEGLError("eglSwapBuffers"); return false; } // Check for messages from the windowing system. int numberOfMessages = XPending(nativeDisplay); for( int i = 0; i < numberOfMessages; i++ ) { XEvent event; XNextEvent(nativeDisplay, &event); switch( event.type ) { // Exit on window close case ClientMessage: // Exit on mouse click case ButtonPress: case DestroyNotify: return false; default: break; } } return true; }
bool Init(GLuint width, GLuint height) { HINSTANCE hInstance = GetModuleHandle(NULL); // Register the windows class WNDCLASS sWC; sWC.style = CS_HREDRAW | CS_VREDRAW; sWC.lpfnWndProc = WndProcedure; //Procedute Callback Event sWC.cbClsExtra = 0; sWC.cbWndExtra = 0; sWC.hInstance = hInstance; sWC.hIcon = 0; sWC.hCursor = 0; sWC.lpszMenuName = 0; sWC.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); sWC.lpszClassName = "OpenGLES2.0"; ATOM registerClass = RegisterClass(&sWC); if (!registerClass) { MessageBox(0, ("Failed to register the window class"), ("Error"), MB_OK | MB_ICONEXCLAMATION); } // Create the eglWindow RECT sRect; SetRect(&sRect, 0, 0, SCREEN_W, SCREEN_H); AdjustWindowRectEx(&sRect, WS_CAPTION | WS_SYSMENU, false, 0); hWnd = CreateWindow( "OpenGLES2.0", "HEngine", WS_VISIBLE | WS_SYSMENU, SCREEN_W / 3, SCREEN_H / 2, sRect.right - sRect.left, sRect.bottom - sRect.top, NULL, NULL, hInstance, NULL); eglWindow = hWnd; // Get the associated device context hDC = GetDC(hWnd); if (!hDC) { MessageBox(0, "Failed to create the device context", "Error", MB_OK|MB_ICONEXCLAMATION); CleanUp(); return false; } eglDisplay = eglGetDisplay(hDC); if(eglDisplay == EGL_NO_DISPLAY) eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY); EGLint iMajorVersion, iMinorVersion; if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) { MessageBox(0, ("eglInitialize() failed."), ("Error"), MB_OK|MB_ICONEXCLAMATION); CleanUp(); return false; } printf("\nVersion: %d %d\n", iMajorVersion, iMinorVersion); const EGLint pi32ConfigAttribs[] = { EGL_LEVEL, 0, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NATIVE_RENDERABLE, EGL_FALSE, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, EGL_SAMPLE_BUFFERS, 1, EGL_NONE }; int iConfigs; if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { MessageBox(0, ("eglChooseConfig() failed."), ("Error"), MB_OK|MB_ICONEXCLAMATION); CleanUp(); return false; } eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL); if(eglSurface == EGL_NO_SURFACE) { eglGetError(); // Clear error eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, NULL, NULL); } if (!TestEGLError(hWnd, "eglCreateWindowSurface")) { CleanUp(); return false; } // Bind the API (It could be OpenGLES or OpenVG) eglBindAPI(EGL_OPENGL_ES_API); EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError(hWnd, "eglCreateContext")) { CleanUp(); return false; } eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError(hWnd, "eglMakeCurrent")) { CleanUp(); return false; } return true; }
bool GLES20Context::Init(EngWindow* pWindow) { eglDisplay = eglGetDisplay(pWindow->GetDisplay()); /* Step 2 - Initialize EGL. EGL has to be initialized with the display obtained in the previous step. We cannot use other EGL functions except eglGetDisplay and eglGetError before eglInitialize has been called. If we're not interested in the EGL version number we can just pass NULL for the second and third parameters. */ EGLint iMajorVersion, iMinorVersion; if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) { printf("Error: eglInitialize() failed.\n"); return false; } /* Step 3 - Make OpenGL ES the current API. EGL provides ways to set up OpenGL ES and OpenVG contexts (and possibly other graphics APIs in the future), so we need to specify the "current API". */ eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) { return false; } /* Step 4 - Specify the required configuration attributes. An EGL "configuration" describes the pixel format and type of surfaces that can be used for drawing. For now we just want to use a 16 bit RGB surface that is a Window surface, i.e. it will be visible on screen. The list has to contain key/value pairs, terminated with EGL_NONE. */ EGLint pi32ConfigAttribs[7]; pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; pi32ConfigAttribs[1] = EGL_WINDOW_BIT; pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE; pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT; pi32ConfigAttribs[4] = EGL_DEPTH_SIZE; pi32ConfigAttribs[5] = 16; pi32ConfigAttribs[6] = EGL_NONE; /* Step 5 - Find a config that matches all requirements. eglChooseConfig provides a list of all available configurations that meet or exceed the requirements given as the second argument. In most cases we just want the first config that meets all criteria, so we can limit the number of configs returned to 1. */ EGLint iConfigs; if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { printf("Error: eglChooseConfig() failed.\n"); return false; } /* Step 6 - Create a surface to draw to. Use the config picked in the previous step and the native window handle when available to create a window surface. A window surface is one that will be visible on screen inside the native display (or fullscreen if there is no windowing system). Pixmaps and pbuffers are surfaces which only exist in off-screen memory. */ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, pWindow->GetWindow(), NULL); if (!TestEGLError("eglCreateWindowSurface")) { return false; } /* Step 7 - Create a context. */ eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError("eglCreateContext")) { return false; } /* Step 8 - Bind the context to the current thread and use our window surface for drawing and reading. Contexts are bound to a thread. This means you don't have to worry about other threads and processes interfering with your OpenGL ES application. We need to specify a surface that will be the target of all subsequent drawing operations, and one that will be the source of read operations. They can be the same surface. */ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError("eglMakeCurrent")) { return false; } /* Step 9 - Draw something with OpenGL ES. At this point everything is initialized and we're ready to use OpenGL ES to draw something on the screen. */ return true; }
static bool setup_egl(NativeDisplayType nativeDisplay, NativeWindowType nativeWindow, EGLDisplay* peglDisplay, EGLSurface* peglSurface, EGLContext* peglContext) { EGLDisplay eglDisplay = EGL_NO_DISPLAY; EGLSurface eglSurface = EGL_NO_SURFACE; EGLContext eglContext = EGL_NO_CONTEXT; EGLConfig eglConfig = 0; /* Step 1 - Get the default display. EGL uses the concept of a "display" which in most environments corresponds to a single physical screen. Since we usually want to draw to the main screen or only have a single screen to begin with, we let EGL pick the default display. Querying other displays is platform specific. */ eglDisplay = eglGetDisplay(nativeDisplay); /* Step 2 - Initialize EGL. EGL has to be initialized with the display obtained in the previous step. We cannot use other EGL functions except eglGetDisplay and eglGetError before eglInitialize has been called. If we're not interested in the EGL version number we can just pass NULL for the second and third parameters. */ EGLint iMajorVersion = 0, iMinorVersion = 0; if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) { printf("Error: eglInitialize() failed.\n"); return false; } /* Step 3 - Specify the required configuration attributes. An EGL "configuration" describes the pixel format and type of surfaces that can be used for drawing. For now we just want to use a 16 bit RGB surface that is a Window surface, i.e. it will be visible on screen. The list has to contain key/value pairs, terminated with EGL_NONE. */ EGLint configAttrs[] = { EGL_BUFFER_SIZE, 32, EGL_DEPTH_SIZE, 24, EGL_NONE }; /* Step 4 - Find a config that matches all requirements. eglChooseConfig provides a list of all available configurations that meet or exceed the requirements given as the second argument. In most cases we just want the first config that meets all criteria, so we can limit the number of configs returned to 1. */ int iConfigs; if (!eglChooseConfig(eglDisplay, configAttrs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { int errcode = eglGetError(); printf("Error: eglChooseConfig() failed. with ErrorCode : 0x%08X\n", errcode); eglTerminate(eglDisplay); return false; } /* Step 5 - Create a surface to draw to. Use the config picked in the previous step and the native window handle when available to create a window surface. A window surface is one that will be visible on screen inside the native display (or fullscreen if there is no windowing system). Pixmaps and pbuffers are surfaces which only exist in off-screen memory. */ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, nativeWindow, NULL); if (!TestEGLError("eglCreateWindowSurface")) { eglTerminate(eglDisplay); return false; } /* Step 6 - Create a context. EGL has to create a context for OpenGL ES. Our OpenGL ES resources like textures will only be valid inside this context (or shared contexts) */ eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL); if (!TestEGLError("eglCreateContext")) { eglTerminate(eglDisplay); return false; } /* Step 7 - Bind the context to the current thread and use our window surface for drawing and reading. Contexts are bound to a thread. This means you don't have to worry about other threads and processes interfering with your OpenGL ES application. We need to specify a surface that will be the target of all subsequent drawing operations, and one that will be the source of read operations. They can be the same surface. */ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError("eglMakeCurrent")) { eglTerminate(eglDisplay); return false; } (*peglDisplay) = eglDisplay; (*peglSurface) = eglSurface; (*peglContext) = eglContext; return true; }
/*!**************************************************************************** @Function main @Input argc Number of arguments @Input argv Command line arguments @Return int result code to OS @Description Main function of the program ******************************************************************************/ bool InitAPI(SHelloAPIData &data) { // EGL variables EGLConfig eglConfig = 0; /* Get the default display. EGL uses the concept of a "display" which in most environments corresponds to a single physical screen. Since we usually want to draw to the main screen or only have a single screen to begin with, we let EGL pick the default display. Querying other displays is platform specific. */ data.eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY); /* Initialize EGL. EGL has to be initialized with the display obtained in the previous step. We cannot use other EGL functions except eglGetDisplay and eglGetError before eglInitialize has been called. If we're not interested in the EGL version number we can just pass NULL for the second and third parameters. */ EGLint iMajorVersion, iMinorVersion; if (!eglInitialize(data.eglDisplay, &iMajorVersion, &iMinorVersion)) { __android_log_print(ANDROID_LOG_ERROR,"OGLESHelloAPI", "Error: eglInitialize() failed.\n"); return false; } /* Specify the required configuration attributes. An EGL "configuration" describes the pixel format and type of surfaces that can be used for drawing. For now we just want to use a 16 bit RGB surface that is a Window surface, i.e. it will be visible on screen. The list has to contain key/value pairs, terminated with EGL_NONE. */ EGLint pi32ConfigAttribs[9]; pi32ConfigAttribs[0] = EGL_RED_SIZE; pi32ConfigAttribs[1] = 5; pi32ConfigAttribs[2] = EGL_GREEN_SIZE; pi32ConfigAttribs[3] = 6; pi32ConfigAttribs[4] = EGL_BLUE_SIZE; pi32ConfigAttribs[5] = 5; pi32ConfigAttribs[6] = EGL_SURFACE_TYPE; pi32ConfigAttribs[7] = EGL_WINDOW_BIT; pi32ConfigAttribs[8] = EGL_NONE; // Get a config that match our criteria EGLint num_config; if(!eglChooseConfig(data.eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &num_config) || num_config != 1) { return false; } EGLint visualID; eglGetConfigAttrib(data.eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &visualID); // Change the format of our window to match our config ANativeWindow_setBuffersGeometry(data.pApp->window, 0, 0, visualID); /* Create a surface to draw to. Use the config picked in the previous step and the native window handle when available to create a window surface. A window surface is one that will be visible on screen inside the native display (or fullscreen if there is no windowing system). Pixmaps and pbuffers are surfaces which only exist in off-screen memory. */ data.eglSurface = eglCreateWindowSurface(data.eglDisplay, eglConfig, data.pApp->window, NULL); if (!TestEGLError("eglCreateWindowSurface")) { return false; } /* Create a context. EGL has to create a context for OpenGL ES. Our OpenGL ES resources like textures will only be valid inside this context (or shared contexts) */ data.eglContext = eglCreateContext(data.eglDisplay, eglConfig, NULL, NULL); if (!TestEGLError("eglCreateContext")) { return false; } /* Step 8 - Bind the context to the current thread and use our window surface for drawing and reading. Contexts are bound to a thread. This means you don't have to worry about other threads and processes interfering with your OpenGL ES application. We need to specify a surface that will be the target of all subsequent drawing operations, and one that will be the source of read operations. They can be the same surface. */ eglMakeCurrent(data.eglDisplay, data.eglSurface, data.eglSurface, data.eglContext); if (!TestEGLError("eglMakeCurrent")) { return false; } /* Step 9 - Draw something with OpenGL ES. At this point everything is initialized and we're ready to use OpenGL ES to draw something on the screen. */ // Sets the clear color. // The colours are passed per channel (red,green,blue,alpha) as float values from 0.0 to 1.0 glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue // We're going to draw a triangle to the screen so create a vertex buffer object for our triangle { // Interleaved vertex data GLfloat afVertices[] = { -0.4f,-0.4f,0.0f, // Position 1.0f ,1.0f ,0.66f,1.0f, // Colour +0.4f,-0.4f,0.0f, 1.0f ,1.0f ,0.66f,1.0f, 0.0f ,0.4f ,0.0f, 1.0f ,1.0f ,0.66f,1.0f }; // Generate the vertex buffer object (VBO) glGenBuffers(1, &data.ui32Vbo); // Bind the VBO so we can fill it with data glBindBuffer(GL_ARRAY_BUFFER, data.ui32Vbo); // Set the buffer's data unsigned int uiSize = 3 * (sizeof(GLfloat) * 7); // Calc afVertices size (3 vertices * stride (7 verttypes per vertex (3 pos + 4 color))) glBufferData(GL_ARRAY_BUFFER, uiSize, afVertices, GL_STATIC_DRAW); } // Enable vertex arrays glEnableClientState(GL_VERTEX_ARRAY); /* Set the vertex pointer. param 1: Number of coordinates per vertex; must be 2, 3, or 4. param 2: GL_FIXED for CommonLite and GL_FLOAT for Common profile. param 3: Specifies the byte offset between consecutive vertexes. param 4: Offset to the start of the first vertex into the VBO. */ glVertexPointer(3, GL_FLOAT, sizeof(float) * 7, 0); // Set color data in the same way glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4,GL_FLOAT,sizeof(float) * 7, (GLvoid*) (sizeof(float) * 3) /*The colour starts after the 3 position values (x,y,z)*/); EGLint w,h; eglQuerySurface(data.eglDisplay, data.eglSurface, EGL_WIDTH, &w); eglQuerySurface(data.eglDisplay, data.eglSurface, EGL_HEIGHT, &h); /* Done - activate requested features */ glViewport(0,0,w,h); return true; }
bool InitialiseEGL(EGLint& w, EGLint& h) { // EGL variables EGLConfig eglConfig = 0; EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; m_eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY); EGLint iMajorVersion, iMinorVersion; if (!eglInitialize(m_eglDisplay, &iMajorVersion, &iMinorVersion)) { DebugLog("Error: eglInitialize() failed."); return false; } eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) { return false; } EGLint pi32ConfigAttribs[11]; pi32ConfigAttribs[0] = EGL_RED_SIZE; pi32ConfigAttribs[1] = 5; pi32ConfigAttribs[2] = EGL_GREEN_SIZE; pi32ConfigAttribs[3] = 6; pi32ConfigAttribs[4] = EGL_BLUE_SIZE; pi32ConfigAttribs[5] = 5; pi32ConfigAttribs[6] = EGL_SURFACE_TYPE; pi32ConfigAttribs[7] = EGL_WINDOW_BIT; pi32ConfigAttribs[8] = EGL_RENDERABLE_TYPE; pi32ConfigAttribs[9] = EGL_OPENGL_ES2_BIT; pi32ConfigAttribs[10] = EGL_NONE; EGLint num_config; if(!eglChooseConfig(m_eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &num_config) || num_config != 1) { return false; } EGLint visualID; eglGetConfigAttrib(m_eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &visualID); // Change the format of our window to match our config ANativeWindow_setBuffersGeometry(m_pApp->window, 0, 0, visualID); m_eglSurface = eglCreateWindowSurface(m_eglDisplay, eglConfig, m_pApp->window, NULL); if (!TestEGLError("eglCreateWindowSurface")) { return false; } m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError("eglCreateContext")) { return false; } eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); if (!TestEGLError("eglMakeCurrent")) { return false; } // Query width and height of the window surface created by utility code eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &w); eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &h); }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) { int i; // Windows variables HWND hWnd=0; HDC hDC=0; // EGL variables EGLDisplay eglDisplay=0; EGLConfig eglConfig=0; EGLSurface eglSurface=0; EGLContext eglContext=0; NativeWindowType eglWindow=0; EGLint pi32ConfigAttribs[128]; unsigned int nWidth; unsigned int nHeight; ATOM registerClass; RECT sRect; EGLint iMajorVersion, iMinorVersion; int iConfigs; /* Step 0 - Create a NativeWindowType that we can use for OpenGL ES output */ // Register the windows class WNDCLASS sWC; sWC.style=CS_HREDRAW | CS_VREDRAW; sWC.lpfnWndProc=WndProc; sWC.cbClsExtra=0; sWC.cbWndExtra=0; sWC.hInstance=hInstance; sWC.hIcon=0; sWC.hCursor=0; sWC.lpszMenuName=0; sWC.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); sWC.lpszClassName=WINDOW_CLASS; nWidth=WINDOW_WIDTH; nHeight=WINDOW_HEIGHT; registerClass=RegisterClass(&sWC); if (!registerClass) { MessageBox(0, _T("Failed to register the window class"), _T("Error"), MB_OK | MB_ICONEXCLAMATION); } // Create the eglWindow SetRect(&sRect, 0, 0, nWidth, nHeight); AdjustWindowRectEx(&sRect, WS_CAPTION | WS_SYSMENU, 0, 0); hWnd=CreateWindow(WINDOW_CLASS, _T("GLU ES Tesselation test"), WS_VISIBLE | WS_SYSMENU, 0, 0, nWidth, nHeight, NULL, NULL, hInstance, NULL); eglWindow=hWnd; // Get the associated device context hDC=GetDC(hWnd); if (!hDC) { MessageBox(0, _T("Failed to create the device context"), _T("Error"), MB_OK|MB_ICONEXCLAMATION); goto cleanup; } /* Step 1 - Get the default display. EGL uses the concept of a "display" which in most environments corresponds to a single physical screen. Since we usually want to draw to the main screen or only have a single screen to begin with, we let EGL pick the default display. Querying other displays is platform specific. */ eglDisplay=eglGetDisplay((NativeDisplayType)hDC); if(eglDisplay==EGL_NO_DISPLAY) { eglDisplay=eglGetDisplay((NativeDisplayType)EGL_DEFAULT_DISPLAY); } /* Step 2 - Initialize EGL. EGL has to be initialized with the display obtained in the previous step. We cannot use other EGL functions except eglGetDisplay and eglGetError before eglInitialize has been called. If we're not interested in the EGL version number we can just pass NULL for the second and third parameters. */ if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) { MessageBox(0, _T("eglInitialize() failed."), _T("Error"), MB_OK | MB_ICONEXCLAMATION); goto cleanup; } /* Step 3 - Specify the required configuration attributes. An EGL "configuration" describes the pixel format and type of surfaces that can be used for drawing. For now we just want to use a 16 bit RGB surface that is a Window surface, i.e. it will be visible on screen. The list has to contain key/value pairs, terminated with EGL_NONE. */ i=0; pi32ConfigAttribs[i++]=EGL_RED_SIZE; pi32ConfigAttribs[i++]=5; pi32ConfigAttribs[i++]=EGL_GREEN_SIZE; pi32ConfigAttribs[i++]=6; pi32ConfigAttribs[i++]=EGL_BLUE_SIZE; pi32ConfigAttribs[i++]=5; pi32ConfigAttribs[i++]=EGL_ALPHA_SIZE; pi32ConfigAttribs[i++]=0; pi32ConfigAttribs[i++]=EGL_DEPTH_SIZE; pi32ConfigAttribs[i++]=16; pi32ConfigAttribs[i++]=EGL_SURFACE_TYPE; pi32ConfigAttribs[i++]=EGL_WINDOW_BIT; pi32ConfigAttribs[i++]=EGL_NONE; /* Step 4 - Find a config that matches all requirements. eglChooseConfig provides a list of all available configurations that meet or exceed the requirements given as the second argument. In most cases we just want the first config that meets all criteria, so we can limit the number of configs returned to 1. */ if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { MessageBox(0, _T("eglChooseConfig() failed."), _T("Error"), MB_OK|MB_ICONEXCLAMATION); goto cleanup; } /* Step 5 - Create a surface to draw to. Use the config picked in the previous step and the native window handle when available to create a window surface. A window surface is one that will be visible on screen inside the native display (or fullscreen if there is no windowing system). Pixmaps and pbuffers are surfaces which only exist in off-screen memory. */ eglSurface=eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL); if (eglSurface==EGL_NO_SURFACE) { eglGetError(); // Clear error eglSurface=eglCreateWindowSurface(eglDisplay, eglConfig, NULL, NULL); } if (!TestEGLError(hWnd, "eglCreateWindowSurface")) { goto cleanup; } /* Step 6 - Create a context. EGL has to create a context for OpenGL ES. Our OpenGL ES resources like textures will only be valid inside this context (or shared contexts) */ eglContext=eglCreateContext(eglDisplay, eglConfig, NULL, NULL); if (!TestEGLError(hWnd, "eglCreateContext")) { goto cleanup; } /* Step 7 - Bind the context to the current thread and use our window surface for drawing and reading. Contexts are bound to a thread. This means you don't have to worry about other threads and processes interfering with your OpenGL ES application. We need to specify a surface that will be the target of all subsequent drawing operations, and one that will be the source of read operations. They can be the same surface. */ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError(hWnd, "eglMakeCurrent")) { goto cleanup; } /* Initialize scene */ init_scene(WINDOW_WIDTH, WINDOW_HEIGHT); /* Render stuff */ do { MSG msg; render_scene(); glFinish(); eglWaitGL(); eglSwapBuffers(eglDisplay, eglSurface); if (done) { break; } PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE); TranslateMessage(&msg); DispatchMessage(&msg); } while(1); /* Step 8 - Terminate OpenGL ES and destroy the window (if present). eglTerminate takes care of destroying any context or surface created with this display, so we don't need to call eglDestroySurface or eglDestroyContext here. */ cleanup: eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(eglDisplay); /* Step 9 - Destroy the eglWindow. Again, this is platform specific and delegated to a separate function. */ // Release the device context if (hDC) { ReleaseDC(hWnd, hDC); } // Destroy the eglWindow if (hWnd) { DestroyWindow(hWnd); } return 0; }
/*!**************************************************************************** @Function main @Input argc Number of arguments @Input argv Command line arguments @Return int result code to OS @Description Main function of the program ******************************************************************************/ int main(int argc, char **argv) { // Variable set in the message handler to finish the demo bool bDemoDone = false; // X11 variables Window x11Window = 0; Display* x11Display = 0; long x11Screen = 0; XVisualInfo* x11Visual = 0; Colormap x11Colormap = 0; // EGL variables EGLDisplay eglDisplay = 0; EGLConfig eglConfig = 0; EGLSurface eglSurface = 0; EGLContext eglContext = 0; GLuint ui32Vbo = 0; // Vertex buffer object handle /* EGL has to create a context for OpenGL ES. Our OpenGL ES resources like textures will only be valid inside this context (or shared contexts). Creation of this context takes place at step 7. */ EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; // Matrix used for projection model view (PMVMatrix) float pfIdentity[] = { 1.0f,0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f, 0.0f,0.0f,0.0f,1.0f }; // Fragment and vertex shaders code const char* const pszFragShader = "\ #version 300 es\n\ layout (location = 0) out lowp vec4 oColour;\ void main (void)\ {\ oColour = vec4(1.0, 1.0, 0.66 ,1.0);\ }"; const char* const pszVertShader = "\ #version 300 es\n\ layout (location = 0) in highp vec4 myVertex;\ uniform mediump mat4 myPMVMatrix;\ void main(void)\ {\ gl_Position = myPMVMatrix * myVertex;\ }"; /* Step 0 - Create a NativeWindowType that we can use it for OpenGL ES output */ Window sRootWindow; XSetWindowAttributes sWA; unsigned int ui32Mask; int i32Depth; int i32Width, i32Height; // Initializes the display and screen x11Display = XOpenDisplay( 0 ); if (!x11Display) { printf("Error: Unable to open X display\n"); goto cleanup; } x11Screen = XDefaultScreen( x11Display ); // Gets the window parameters sRootWindow = RootWindow(x11Display, x11Screen); i32Depth = DefaultDepth(x11Display, x11Screen); x11Visual = new XVisualInfo; XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, x11Visual); if (!x11Visual) { printf("Error: Unable to acquire visual\n"); goto cleanup; } x11Colormap = XCreateColormap( x11Display, sRootWindow, x11Visual->visual, AllocNone ); sWA.colormap = x11Colormap; // Add to these for handling other events sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; i32Width = WINDOW_WIDTH < XDisplayWidth(x11Display, x11Screen) ? WINDOW_WIDTH : XDisplayWidth(x11Display, x11Screen); i32Height = WINDOW_HEIGHT < XDisplayHeight(x11Display,x11Screen) ? WINDOW_HEIGHT: XDisplayHeight(x11Display,x11Screen); // Creates the X11 window x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, i32Width, i32Height, 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA); XMapWindow(x11Display, x11Window); XFlush(x11Display); /* Step 1 - Get the default display. EGL uses the concept of a "display" which in most environments corresponds to a single physical screen. Since we usually want to draw to the main screen or only have a single screen to begin with, we let EGL pick the default display. Querying other displays is platform specific. */ eglDisplay = eglGetDisplay((EGLNativeDisplayType)x11Display); /* Step 2 - Initialize EGL. EGL has to be initialized with the display obtained in the previous step. We cannot use other EGL functions except eglGetDisplay and eglGetError before eglInitialize has been called. If we're not interested in the EGL version number we can just pass NULL for the second and third parameters. */ EGLint iMajorVersion, iMinorVersion; if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) { printf("Error: eglInitialize() failed.\n"); goto cleanup; } /* Step 3 - Make OpenGL ES the current API. EGL provides ways to set up OpenGL ES and OpenVG contexts (and possibly other graphics APIs in the future), so we need to specify the "current API". */ eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) { goto cleanup; } /* Step 4 - Specify the required configuration attributes. An EGL "configuration" describes the pixel format and type of surfaces that can be used for drawing. For now we just want to use a 16 bit RGB surface that is a Window surface, i.e. it will be visible on screen. The list has to contain key/value pairs, terminated with EGL_NONE. */ EGLint pi32ConfigAttribs[5]; pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; pi32ConfigAttribs[1] = EGL_WINDOW_BIT; pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE; pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT; pi32ConfigAttribs[4] = EGL_NONE; /* Step 5 - Find a config that matches all requirements. eglChooseConfig provides a list of all available configurations that meet or exceed the requirements given as the second argument. In most cases we just want the first config that meets all criteria, so we can limit the number of configs returned to 1. */ EGLint iConfigs; if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) { printf("Error: eglChooseConfig() failed.\n"); goto cleanup; } /* Step 6 - Create a surface to draw to. Use the config picked in the previous step and the native window handle when available to create a window surface. A window surface is one that will be visible on screen inside the native display (or fullscreen if there is no windowing system). Pixmaps and pbuffers are surfaces which only exist in off-screen memory. */ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)x11Window, NULL); if (!TestEGLError("eglCreateWindowSurface")) { goto cleanup; } /* Step 7 - Create a context. */ eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError("eglCreateContext")) { goto cleanup; } /* Step 8 - Bind the context to the current thread and use our window surface for drawing and reading. Contexts are bound to a thread. This means you don't have to worry about other threads and processes interfering with your OpenGL ES application. We need to specify a surface that will be the target of all subsequent drawing operations, and one that will be the source of read operations. They can be the same surface. */ eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (!TestEGLError("eglMakeCurrent")) { goto cleanup; } /* Step 9 - Draw something with OpenGL ES. At this point everything is initialized and we're ready to use OpenGL ES to draw something on the screen. */ GLuint uiFragShader, uiVertShader; // Used to hold the fragment and vertex shader handles GLuint uiProgramObject; // Used to hold the program handle (made out of the two previous shaders // Create the fragment shader object uiFragShader = glCreateShader(GL_FRAGMENT_SHADER); // Load the source code into it glShaderSource(uiFragShader, 1, (const char**)&pszFragShader, NULL); // Compile the source code glCompileShader(uiFragShader); // Check if compilation succeeded GLint bShaderCompiled; glGetShaderiv(uiFragShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { // An error happened, first retrieve the length of the log message int i32InfoLogLength, i32CharsWritten; glGetShaderiv(uiFragShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); // Allocate enough space for the message and retrieve it char* pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); // Displays the error printf("Failed to compile fragment shader: %s\n", pszInfoLog); delete [] pszInfoLog; goto cleanup; } // Loads the vertex shader in the same way uiVertShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(uiVertShader, 1, (const char**)&pszVertShader, NULL); glCompileShader(uiVertShader); glGetShaderiv(uiVertShader, GL_COMPILE_STATUS, &bShaderCompiled); if (!bShaderCompiled) { int i32InfoLogLength, i32CharsWritten; glGetShaderiv(uiVertShader, GL_INFO_LOG_LENGTH, &i32InfoLogLength); char* pszInfoLog = new char[i32InfoLogLength]; glGetShaderInfoLog(uiVertShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog); printf("Failed to compile vertex shader: %s\n", pszInfoLog); delete [] pszInfoLog; goto cleanup; } // Create the shader program uiProgramObject = glCreateProgram(); // Attach the fragment and vertex shaders to it glAttachShader(uiProgramObject, uiFragShader); glAttachShader(uiProgramObject, uiVertShader); // Bind the custom vertex attribute "myVertex" to location VERTEX_ARRAY glBindAttribLocation(uiProgramObject, VERTEX_ARRAY, "myVertex"); // Link the program glLinkProgram(uiProgramObject); // Check if linking succeeded in the same way we checked for compilation success GLint bLinked; glGetProgramiv(uiProgramObject, GL_LINK_STATUS, &bLinked); if (!bLinked) { int ui32InfoLogLength, ui32CharsWritten; glGetProgramiv(uiProgramObject, GL_INFO_LOG_LENGTH, &ui32InfoLogLength); char* pszInfoLog = new char[ui32InfoLogLength]; glGetProgramInfoLog(uiProgramObject, ui32InfoLogLength, &ui32CharsWritten, pszInfoLog); printf("Failed to link program: %s\n", pszInfoLog); delete [] pszInfoLog; goto cleanup; } // Actually use the created program glUseProgram(uiProgramObject); // Sets the clear color. // The colours are passed per channel (red,green,blue,alpha) as float values from 0.0 to 1.0 glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue // We're going to draw a triangle to the screen so create a vertex buffer object for our triangle { // Interleaved vertex data GLfloat afVertices[] = { -0.4f,-0.4f,0.0f, // Position 0.4f ,-0.4f,0.0f, 0.0f ,0.4f ,0.0f}; // Generate the vertex buffer object (VBO) glGenBuffers(1, &ui32Vbo); // Bind the VBO so we can fill it with data glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo); // Set the buffer's data unsigned int uiSize = 3 * (sizeof(GLfloat) * 3); // Calc afVertices size (3 vertices * stride (3 GLfloats per vertex)) glBufferData(GL_ARRAY_BUFFER, uiSize, afVertices, GL_STATIC_DRAW); } // Draws a triangle for 800 frames for(int i = 0; i < 800; ++i) { // Check if the message handler finished the demo if (bDemoDone) break; /* Clears the color buffer. glClear() can also be used to clear the depth or stencil buffer (GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT) */ glClear(GL_COLOR_BUFFER_BIT); /* Bind the projection model view matrix (PMVMatrix) to the associated uniform variable in the shader */ // First gets the location of that variable in the shader using its name int i32Location = glGetUniformLocation(uiProgramObject, "myPMVMatrix"); // Then passes the matrix to that variable glUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity); /* Enable the custom vertex attribute at index VERTEX_ARRAY. We previously binded that index to the variable in our shader "vec4 MyVertex;" */ glEnableVertexAttribArray(VERTEX_ARRAY); // Sets the vertex data to this attribute index glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0); /* Draws a non-indexed triangle array from the pointers previously given. This function allows the use of other primitive types : triangle strips, lines, ... For indexed geometry, use the function glDrawElements() with an index list. */ glDrawArrays(GL_TRIANGLES, 0, 3); /* Swap Buffers. Brings to the native display the current render surface. */ eglSwapBuffers(eglDisplay, eglSurface); if (!TestEGLError("eglSwapBuffers")) { goto cleanup; } // Managing the X11 messages int i32NumMessages = XPending( x11Display ); for( int i = 0; i < i32NumMessages; i++ ) { XEvent event; XNextEvent( x11Display, &event ); switch( event.type ) { // Exit on mouse click case ButtonPress: bDemoDone = true; break; default: break; } } } // Frees the OpenGL handles for the program and the 2 shaders glDeleteProgram(uiProgramObject); glDeleteShader(uiFragShader); glDeleteShader(uiVertShader); // Delete the VBO as it is no longer needed glDeleteBuffers(1, &ui32Vbo); /* Step 10 - Terminate OpenGL ES and destroy the window (if present). eglTerminate takes care of destroying any context or surface created with this display, so we don't need to call eglDestroySurface or eglDestroyContext here. */ cleanup: eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ; eglTerminate(eglDisplay); /* Step 11 - Destroy the eglWindow. Again, this is platform specific and delegated to a separate function */ if (x11Window) XDestroyWindow(x11Display, x11Window); if (x11Colormap) XFreeColormap( x11Display, x11Colormap ); if (x11Display) XCloseDisplay(x11Display); delete x11Visual; return 0; }
//egl init int common_eglinit(struct globalStruct* globals, int testID, int surfaceType, NATIVE_PIXMAP_STRUCT** pNativePixmapPtr) { EGLint iMajorVersion, iMinorVersion; EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; globals->eglDisplay = eglGetDisplay((int)0); if (!eglInitialize(globals->eglDisplay, &iMajorVersion, &iMinorVersion)) return 1; eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) return 1; EGLint pi32ConfigAttribs[5]; pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; pi32ConfigAttribs[1] = EGL_WINDOW_BIT | EGL_PIXMAP_BIT; pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE; pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT; pi32ConfigAttribs[4] = EGL_NONE; int iConfigs; if (!eglChooseConfig(globals->eglDisplay, pi32ConfigAttribs, &globals->eglConfig, 1, &iConfigs) || (iConfigs != 1)) { SGXPERF_ERR_printf("Error: eglChooseConfig() failed.\n"); return 1; } if(surfaceType == SGXPERF_SURFACE_TYPE_WINDOW) globals->eglSurface = eglCreateWindowSurface(globals->eglDisplay, globals->eglConfig, (EGLNativeWindowType) NULL, NULL); else if(surfaceType == SGXPERF_SURFACE_TYPE_PIXMAP_16) { common_create_native_pixmap(SGXPERF_RGB565, globals->inTextureWidth, globals->inTextureHeight, pNativePixmapPtr); globals->eglSurface = eglCreatePixmapSurface(globals->eglDisplay, globals->eglConfig, (EGLNativePixmapType)*pNativePixmapPtr, NULL); } else if(surfaceType == SGXPERF_SURFACE_TYPE_PIXMAP_32) { common_create_native_pixmap(SGXPERF_ARGB8888, globals->inTextureWidth, globals->inTextureHeight, pNativePixmapPtr); globals->eglSurface = eglCreatePixmapSurface(globals->eglDisplay, globals->eglConfig, (EGLNativePixmapType)*pNativePixmapPtr, NULL); } else return 999; if (!TestEGLError("eglCreateSurface")) return 1; if(testID == 14) //Create one pixmap surface for context switch latency check { common_create_native_pixmap(SGXPERF_RGB565, globals->inTextureWidth, globals->inTextureHeight, pNativePixmapPtr); globals->eglSurface2 = eglCreatePixmapSurface(globals->eglDisplay, globals->eglConfig, (EGLNativePixmapType)*pNativePixmapPtr, NULL); } if (!TestEGLError("eglCreateSurface")) return 1; globals->eglContext = eglCreateContext(globals->eglDisplay, globals->eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError("eglCreateContext")) return 1; eglMakeCurrent(globals->eglDisplay, globals->eglSurface, globals->eglSurface, globals->eglContext); if (!TestEGLError("eglMakeCurrent")) return 1; eglSwapInterval(globals->eglDisplay, 1); if (!TestEGLError("eglSwapInterval")) return 1; eglQuerySurface(globals->eglDisplay, globals->eglSurface, EGL_WIDTH, &globals->windowWidth); eglQuerySurface(globals->eglDisplay, globals->eglSurface, EGL_HEIGHT, &globals->windowHeight); SGXPERF_printf("Window width=%d, Height=%d\n", globals->windowWidth, globals->windowHeight); return 0; }
static DFBResult InitEGL( PVR2DData *pvr2d ) { EGLint iMajorVersion, iMinorVersion; EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; pvr2d->eglDisplay = eglGetDisplay((int)0); if (!eglInitialize(pvr2d->eglDisplay, &iMajorVersion, &iMinorVersion)) return DFB_INIT; pvr2d->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); if (pvr2d->eglCreateImageKHR == NULL) { D_ERROR( "DirectFB/PVR2D: eglCreateImageKHR not found!\n" ); return DFB_UNSUPPORTED; } pvr2d->glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES"); if (pvr2d->glEGLImageTargetTexture2DOES == NULL) { D_ERROR( "DirectFB/PVR2D: glEGLImageTargetTexture2DOES not found!\n" ); return DFB_UNSUPPORTED; } eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) return DFB_INIT; EGLint pi32ConfigAttribs[5]; pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; pi32ConfigAttribs[1] = EGL_WINDOW_BIT | EGL_PIXMAP_BIT; pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE; pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT; pi32ConfigAttribs[4] = EGL_NONE; int iConfigs; if (!eglChooseConfig(pvr2d->eglDisplay, pi32ConfigAttribs, &pvr2d->eglConfig, 1, &iConfigs) || (iConfigs != 1)) { D_ERROR("DirectFB/PVR2D: eglChooseConfig() failed.\n"); return DFB_INIT; } pvr2d->nativePixmap.ePixelFormat = 0; pvr2d->nativePixmap.eRotation = 0; pvr2d->nativePixmap.lWidth = pvr2d->lDisplayWidth; pvr2d->nativePixmap.lHeight = pvr2d->lDisplayHeight; pvr2d->nativePixmap.lStride = pvr2d->lStride; pvr2d->nativePixmap.lSizeInBytes = pvr2d->pFBMemInfo->ui32MemSize; pvr2d->nativePixmap.pvAddress = pvr2d->pFBMemInfo->ui32DevAddr; pvr2d->nativePixmap.lAddress = (long) pvr2d->pFBMemInfo->pBase; pvr2d->eglSurface = eglCreatePixmapSurface( pvr2d->eglDisplay, pvr2d->eglConfig, &pvr2d->nativePixmap, NULL ); if (!TestEGLError("eglCreatePixmapSurface")) return DFB_INIT; pvr2d->eglContext = eglCreateContext(pvr2d->eglDisplay, pvr2d->eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError("eglCreateContext")) return DFB_INIT; eglMakeCurrent( pvr2d->eglDisplay, pvr2d->eglSurface, pvr2d->eglSurface, pvr2d->eglContext ); if (!TestEGLError("eglMakeCurrent")) return DFB_INIT; eglSwapInterval( pvr2d->eglDisplay, 1 ); if (!TestEGLError("eglSwapInterval")) return DFB_INIT; return DFB_OK; }