int tpw_window_create(const char *title, unsigned int window_w, unsigned int window_h, unsigned int fullscreen, const unsigned int bpp) { unsigned int mode; #ifdef HAVE_GLES EGLint configs_avail = 0; SDL_SysWMinfo sysinfo; #endif #ifndef HAVE_GLES mode = SDL_OPENGL; #else mode = SDL_SWSURFACE; #endif if (fullscreen) mode |= SDL_FULLSCREEN; SDL_WM_SetCaption(title, title); #ifdef HAVE_GLES if (!(tpw.XDisplay = XOpenDisplay(NULL))) { fprintf(stderr, "tpw_window_create(): Unable to open the default display\n"); return 0; } #ifdef RASPBERRYPI bcm_host_init(); if (!(tpw.eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY))) { fprintf(stderr, "tpw_window_create(): Unable to get a display handle from EGL!!\n"); return 0; } #else if (!(tpw.eglDisplay = eglGetDisplay((EGL_DEFAULT_DISPLAY)))) { fprintf(stderr, "tpw_window_create(): Unable to get a display handle from EGL\n"); return 0; } #endif if (!eglInitialize(tpw.eglDisplay, NULL, NULL)) { fprintf(stderr, "tpw_window_create(): Unable to initialize EGL\n"); return 0; } #endif if (!(tpw.screen = SDL_SetVideoMode(window_w, window_h, bpp, mode))) return 0; #ifdef HAVE_GLES if (eglChooseConfig(tpw.eglDisplay, egl_config_attrib, &tpw.eglConfig, 1, &configs_avail) != EGL_TRUE) { fprintf(stderr, "tpw_window_create(): Unable to find a config for EGL(%i)\n", configs_avail); return 0; } SDL_VERSION(&sysinfo.version); if (SDL_GetWMInfo(&sysinfo) <= 0) { fprintf(stderr, "tpw_window_create(): Unable to get a window handle\n"); return 0; } #ifndef RASPBERRYPI if ((tpw.eglSurface = eglCreateWindowSurface(tpw.eglDisplay, tpw.eglConfig, (EGLNativeWindowType) NULL, NULL)) == EGL_NO_SURFACE) { fprintf(stderr, "tpw_window_create(): Unable to create an EGL surface\n"); return 0; } #else /* RaspberryPi's videosystem är helt jävla efterblivet. Den som designade det här och tyckte att det var en bra idé kan gå och knulla sig själv med en motorsåg... Det finns inte ord som kan beskriva hur mycket jag hatar härket. */ XWindowAttributes xwa; VC_RECT_T dst_rect, src_rect; DISPMANX_UPDATE_HANDLE_T dispman_update; DISPMANX_DISPLAY_HANDLE_T dispman_display; XGetWindowAttributes(tpw.XDisplay, sysinfo.info.x11.window, &xwa); src_rect.x = 0; src_rect.y = 0; src_rect.width = window_w << 16; src_rect.height = window_h << 16; dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = window_w; dst_rect.height = window_h; dispman_display = vc_dispmanx_display_open(0); dispman_update = vc_dispmanx_update_start(0); tpw.nativewindow.element = vc_dispmanx_element_add(dispman_update, dispman_display, 0, &dst_rect, 0, &src_rect, DISPMANX_PROTECTION_NONE, 0, 0, 0); tpw.nativewindow.width = window_w; tpw.nativewindow.height = window_h; vc_dispmanx_update_submit_sync(dispman_update); if ((tpw.eglSurface = eglCreateWindowSurface(tpw.eglDisplay, tpw.eglConfig, (EGLNativeWindowType) &tpw.nativewindow, NULL)) == EGL_NO_SURFACE) { fprintf(stderr, "tpw_window_create(): Unable to create an EGL surface %X\n", eglGetError()); return 0; } #endif eglBindAPI(EGL_OPENGL_ES_API); if ((tpw.eglContext = eglCreateContext(tpw.eglDisplay, tpw.eglConfig, NULL, NULL)) == EGL_NO_CONTEXT) { fprintf(stderr, "tpw_window_create(): Unable to create an EGL context\n"); return 0; } if (eglMakeCurrent(tpw.eglDisplay, tpw.eglSurface, tpw.eglSurface, tpw.eglContext) == EGL_FALSE) { fprintf(stderr, "tpw_window_create(): Unable to make the EGL context current\n"); return 0; } #endif #ifndef NO_GLX #ifndef HAVE_GLES // glXSwapIntervalEXT(1); #endif #endif return 1; }
EGLNativeWindowType _glusCreateNativeWindowType(const char* title, const GLUSint width, const GLUSint height, const GLUSboolean fullscreen, const GLUSboolean noResize) { const SDL_VideoInfo* videoInfo; // DISPMANX_UPDATE_HANDLE_T dispmanUpdate; DISPMANX_ELEMENT_HANDLE_T dispmanElement; VC_RECT_T dstRect; VC_RECT_T srcRect; VC_DISPMANX_ALPHA_T dispmanAlpha; int32_t success; int32_t windowWidth; int32_t windowHeight; glusLogPrint(GLUS_LOG_INFO, "Parameters 'title' and 'noResize' are not used"); // Initialize graphics system bcm_host_init(); // Set fullscreen, if wanted if (fullscreen) { const uint32_t MAX_SUPPORTED_MODES = 128; HDMI_RES_GROUP_T group = HDMI_RES_GROUP_DMT; TV_SUPPORTED_MODE_NEW_T supportedModes[MAX_SUPPORTED_MODES]; int32_t i, numberSupportedModes; numberSupportedModes = vc_tv_hdmi_get_supported_modes_new(group, supportedModes, MAX_SUPPORTED_MODES, 0, 0); for (i = 0; i < numberSupportedModes; i++) { if (supportedModes[i].width == (uint32_t)width && supportedModes[i].height == (uint32_t)height && supportedModes[i].frame_rate >= 60) { break; } } if (i == numberSupportedModes) { glusLogPrint(GLUS_LOG_ERROR, "No matching display resolution found: ", width, height); return EGL_NO_SURFACE ; } vc_tv_register_callback(resizeDone, 0); if (vc_tv_hdmi_power_on_explicit_new(group, supportedModes[i].group, supportedModes[i].code) != 0) { vc_tv_unregister_callback(resizeDone); glusLogPrint(GLUS_LOG_ERROR, "Could not switch to full screen: ", width, height); return EGL_NO_SURFACE ; } waitResizeDone(); vc_tv_unregister_callback(resizeDone); windowWidth = width; windowHeight = height; _fullscreen = GLUS_TRUE; } else { windowWidth = width; windowHeight = height; } // _nativeDisplay = vc_dispmanx_display_open(0 /* LCD */); if (!_nativeDisplay) { glusLogPrint(GLUS_LOG_ERROR, "Could not open display"); return EGL_NO_SURFACE ; } // if (SDL_Init(SDL_INIT_VIDEO) != 0) { glusLogPrint(GLUS_LOG_ERROR, "Could not initialize SDL"); return EGL_NO_SURFACE ; } videoInfo = SDL_GetVideoInfo(); if (!videoInfo) { glusLogPrint(GLUS_LOG_ERROR, "Could not get video info for SDL"); return EGL_NO_SURFACE ; } if (!SDL_SetVideoMode(videoInfo->current_w, videoInfo->current_h, videoInfo->vfmt->BitsPerPixel, SDL_HWSURFACE)) { glusLogPrint(GLUS_LOG_ERROR, "Set video mode for SDL failed"); return EGL_NO_SURFACE ; } SDL_ShowCursor(SDL_DISABLE); // dstRect.x = 0; dstRect.y = 0; dstRect.width = windowWidth; dstRect.height = windowHeight; srcRect.x = 0; srcRect.y = 0; srcRect.width = windowWidth << 16; srcRect.height = windowHeight << 16; dispmanAlpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; dispmanAlpha.mask = 0xFFFFFFFF; dispmanAlpha.opacity = 255; dispmanUpdate = vc_dispmanx_update_start(0); dispmanElement = vc_dispmanx_element_add(dispmanUpdate, _nativeDisplay, 0 /*layer*/, &dstRect, 0 /*src*/, &srcRect, DISPMANX_PROTECTION_NONE, &dispmanAlpha, 0/*clamp*/, 0/*transform*/); success = vc_dispmanx_update_submit_sync(dispmanUpdate); if (!dispmanElement || success < 0) { glusLogPrint(GLUS_LOG_ERROR, "Could not add element"); return EGL_NO_SURFACE ; } _width = windowWidth; _height = windowHeight; _nativeWindow.element = dispmanElement; _nativeWindow.width = windowWidth; _nativeWindow.height = windowHeight; _nativeWindowCreated = GLUS_TRUE; return (EGLNativeWindowType)&_nativeWindow; }
/*********************************************************** * Name: init_ogl * * Arguments: * CUBE_STATE_T *state - holds OGLES model info * * Description: Sets the display, OpenGL|ES context and screen stuff * * Returns: void * ***********************************************************/ static void init_ogl(CUBE_STATE_T *state) { int32_t success = 0; EGLBoolean result; EGLint num_config; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; static const EGLint attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, //EGL_SAMPLES, 4, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; EGLConfig config; // get an EGL display connection state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); assert(state->display!=EGL_NO_DISPLAY); // initialize the EGL display connection result = eglInitialize(state->display, NULL, NULL); assert(EGL_FALSE != result); // get an appropriate EGL frame buffer configuration // this uses a BRCM extension that gets the closest match, rather than standard which returns anything that matches result = eglSaneChooseConfigBRCM(state->display, attribute_list, &config, 1, &num_config); assert(EGL_FALSE != result); // create an EGL rendering context state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL); assert(state->context!=EGL_NO_CONTEXT); // create an EGL window surface success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height); assert( success >= 0 ); dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = state->screen_width; dst_rect.height = state->screen_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = state->screen_width << 16; src_rect.height = state->screen_height << 16; dispman_display = vc_dispmanx_display_open( 0 /* LCD */); dispman_update = vc_dispmanx_update_start( 0 ); dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); nativewindow.element = dispman_element; nativewindow.width = state->screen_width; nativewindow.height = state->screen_height; vc_dispmanx_update_submit_sync( dispman_update ); state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL ); assert(state->surface != EGL_NO_SURFACE); // connect the context to the surface result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); assert(EGL_FALSE != result); // Set background color and clear buffers glClearColor(0.15f, 0.25f, 0.35f, 1.0f); glClear( GL_COLOR_BUFFER_BIT ); glClear( GL_DEPTH_BUFFER_BIT ); glShadeModel(GL_FLAT); // Enable back face culling. glEnable(GL_CULL_FACE); }
/// // esCreateWindow() // // width - width of window to create // height - height of window to create // flags - bitwise or of window creation flags // ES_WINDOW_ALPHA - specifies that the framebuffer should have alpha // ES_WINDOW_DEPTH - specifies that a depth buffer should be created // ES_WINDOW_STENCIL - specifies that a stencil buffer should be created // ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created // GLboolean ESUTIL_API esCreateWindow(ESContext *esContext, GLint width, GLint height, GLuint flags) { EGLint attribList[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; if (esContext == NULL) { return GL_FALSE; } esContext->width = width; esContext->height = height; int32_t success = 0; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; int display_width; int display_height; // create an EGL window surface, passing context width/height success = graphics_get_display_size(0 /* LCD */, &display_width, &display_height); if (success < 0) { return EGL_FALSE; } dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = display_width; dst_rect.height = display_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = display_width << 16; src_rect.height = display_height << 16; dispman_display = vc_dispmanx_display_open(0 /* LCD */); dispman_update = vc_dispmanx_update_start(0); dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); nativewindow.element = dispman_element; nativewindow.width = display_width; nativewindow.height = display_height; vc_dispmanx_update_submit_sync(dispman_update); esContext->hWnd = &nativewindow; esContext->width = display_width; esContext->height = display_height; EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; EGLDisplay display; EGLContext context; EGLSurface surface; EGLConfig config; EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (display == EGL_NO_DISPLAY) { return GL_FALSE; } if (!eglInitialize(display, &majorVersion, &minorVersion)) { return GL_FALSE; } // Get configs if (!eglGetConfigs(display, NULL, 0, &numConfigs)) { return GL_FALSE; } // Choose config if (!eglChooseConfig(display, attribList, &config, 1, &numConfigs)) { return GL_FALSE; } // Create a surface surface = eglCreateWindowSurface(display, config, esContext->hWnd, NULL); if (surface == EGL_NO_SURFACE) { return GL_FALSE; } // Create a GL context context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); if (context == EGL_NO_CONTEXT) { return GL_FALSE; } // Make the context current if (!eglMakeCurrent(display, surface, surface, context)) { return GL_FALSE; } esContext->eglDisplay = display; esContext->eglSurface = surface; esContext->eglContext = context; return GL_TRUE; }
//display int init_display() { int32_t success = 0; EGLBoolean result; EGLint num_config; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; EGLConfig config; //creates problem is func eglCreateContext static const EGLint attribute_list[] = { //EGL_COLOR_BUFFER_TYPE, EGL_LUMINANCE_BUFFER, //EGL_RGB_BUFFER EGL_RED_SIZE, 8, // default is 0 EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, //EGL_LUMINANCE_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; static const EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; memset( &m_display, 0, sizeof(display) ); bcm_host_init(); // must be called be4 any gpu function is called m_display.display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (m_display.display==EGL_NO_DISPLAY) { printf("init_opengl : error in eglGetDisplay\n"); exit(-1); } result = eglInitialize(m_display.display, NULL, NULL); if (EGL_FALSE == result) { printf("init_opengl : error in initializing EGL Display\n"); exit(-1); } result = eglChooseConfig(m_display.display, attribute_list, &config, 17*sizeof(attribute_list[0]), &num_config); if (EGL_FALSE == result) { printf("init_opengl : error in getting egl frame buffer configuration\n"); exit(-1); } result = eglBindAPI(EGL_OPENGL_ES_API); if (EGL_FALSE == result) { printf("init_opengl : error in binding api\n"); exit(-1); } m_display.context = eglCreateContext(m_display.display, config, EGL_NO_CONTEXT, context_attributes); if (m_display.context==EGL_NO_CONTEXT) { printf("init_opengl : error in creating context . \n"); exit(-1); } // create an EGL window surface (video core api)(bug 1920*1080 always)(only for rpi) success = graphics_get_display_size(0 /*display number*/, &m_display.scr_width, &m_display.scr_height); if ( success < 0 ) { printf("init_opengl : error in creating EGL window surface\n"); exit(-1); } if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 1.\n"); exit(-1); } dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = m_display.scr_width; dst_rect.height = m_display.scr_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = m_display.scr_width << 16; src_rect.height = m_display.scr_height << 16; dispman_display = vc_dispmanx_display_open( 0 /*display number*/); dispman_update = vc_dispmanx_update_start( 0 ); dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, (DISPMANX_TRANSFORM_T)0/*transform*/); m_display.nativewindow.element = dispman_element; m_display.nativewindow.width = m_display.scr_width; m_display.nativewindow.height = m_display.scr_height; vc_dispmanx_update_submit_sync( dispman_update ); if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 2.\n"); exit(-1); } m_display.surface = eglCreateWindowSurface( m_display.display, config, &m_display.nativewindow, NULL ); if(m_display.surface == EGL_NO_SURFACE) { printf("init_opengl : error could not create window surface\n"); exit(-1); } // connect the context to the surface result = eglMakeCurrent(m_display.display, m_display.surface, m_display.surface, m_display.context); if ( EGL_FALSE == result ) { printf("init_opengl : error - could not connect context to surface\n"); exit(-1); } if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 3.\n"); exit(-1); } glClear( GL_COLOR_BUFFER_BIT ); glViewport ( 0, 0, m_display.scr_width, m_display.scr_height ); if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 4.\n"); exit(-1); } m_display.scr_aspect_ratio = (float) ( ((float)m_display.scr_width) / ((float)m_display.scr_height) ); return(0); }
/** @brief Obtain a reference to the system's native window * @param width : desired pixel width of the window (not used by all platforms) * @param height : desired pixel height of the window (not used by all platforms) * @return : 0 if the function passed, else 1 */ int8_t GetNativeWindow( uint16_t width, uint16_t height ) { nativeWindow = 0; #if defined(WIZ) || defined(CAANOO) nativeWindow = (NativeWindowType)malloc(16*1024); if(nativeWindow == NULL) { printf( "EGLport ERROR: Memory for window Failed\n" ); return 1; } #elif defined(RPI) EGLBoolean result; uint32_t screen_width, screen_height; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; /* create an EGL window surface */ result = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height); if(result < 0) { printf( "EGLport ERROR: RPi graphicget_display_size failed\n" ); return 1; } dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = screen_width; dst_rect.height = screen_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = width << 16; src_rect.height = height << 16; dispman_display = vc_dispmanx_display_open( 0 /* LCD */); dispman_update = vc_dispmanx_update_start( 0 ); dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0 /*layer*/, &dst_rect, 0 /*src*/, &src_rect, DISPMANX_PROTECTION_NONE, (VC_DISPMANX_ALPHA_T*)0 /*alpha*/, (DISPMANX_CLAMP_T*)0 /*clamp*/, (DISPMANX_TRANSFORM_T)0 /*transform*/); nativewindow.element = dispman_element; nativewindow.width = screen_width; nativewindow.height = screen_height; vc_dispmanx_update_submit_sync( dispman_update ); nativeWindow = (NativeWindowType)&nativewindow; #else /* default */ if (eglSettings[CFG_MODE] == RENDER_RAW) /* RAW FB mode */ { nativeWindow = 0; } else if(eglSettings[CFG_MODE] == RENDER_SDL) /* SDL/X11 mode */ { #if defined(USE_EGL_SDL) /* SDL_GetWMInfo is populated when display was opened */ nativeWindow = (NativeWindowType)sysWmInfo.info.x11.window; if (nativeWindow == 0) { printf( "EGLport ERROR: unable to get window!\n" ); return 1; } #else printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" ); #endif } else { printf( "EGLport ERROR: Unknown EGL render mode %d!\n", eglSettings[CFG_MODE] ); return 1; } #endif /* WIZ / CAANOO */ return 0; }
void GlContext::create(uint32_t _width, uint32_t _height) { # if BX_PLATFORM_RPI bcm_host_init(); # endif // BX_PLATFORM_RPI m_eglLibrary = eglOpen(); if (NULL == g_platformData.context) { # if BX_PLATFORM_RPI g_platformData.ndt = EGL_DEFAULT_DISPLAY; # endif // BX_PLATFORM_RPI BX_UNUSED(_width, _height); EGLNativeDisplayType ndt = (EGLNativeDisplayType)g_platformData.ndt; EGLNativeWindowType nwh = (EGLNativeWindowType )g_platformData.nwh; # if BX_PLATFORM_WINDOWS if (NULL == g_platformData.ndt) { ndt = GetDC( (HWND)g_platformData.nwh); } # endif // BX_PLATFORM_WINDOWS m_display = eglGetDisplay(ndt); BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display); EGLint major = 0; EGLint minor = 0; EGLBoolean success = eglInitialize(m_display, &major, &minor); BGFX_FATAL(success && major >= 1 && minor >= 3, Fatal::UnableToInitialize, "Failed to initialize %d.%d", major, minor); BX_TRACE("EGL info:"); const char* clientApis = eglQueryString(m_display, EGL_CLIENT_APIS); BX_TRACE(" APIs: %s", clientApis); BX_UNUSED(clientApis); const char* vendor = eglQueryString(m_display, EGL_VENDOR); BX_TRACE(" Vendor: %s", vendor); BX_UNUSED(vendor); const char* version = eglQueryString(m_display, EGL_VERSION); BX_TRACE("Version: %s", version); BX_UNUSED(version); const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS); BX_TRACE("Supported EGL extensions:"); dumpExtensions(extensions); EGLint attrs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, # if BX_PLATFORM_ANDROID EGL_DEPTH_SIZE, 16, # else EGL_DEPTH_SIZE, 24, # endif // BX_PLATFORM_ EGL_STENCIL_SIZE, 8, EGL_NONE }; EGLint numConfig = 0; success = eglChooseConfig(m_display, attrs, &m_config, 1, &numConfig); BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig"); # if BX_PLATFORM_ANDROID EGLint format; eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry( (ANativeWindow*)g_platformData.nwh, _width, _height, format); # elif BX_PLATFORM_RPI DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0); DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0); VC_RECT_T dstRect = { 0, 0, int32_t(_width), int32_t(_height) }; VC_RECT_T srcRect = { 0, 0, int32_t(_width) << 16, int32_t(_height) << 16 }; DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate , dispmanDisplay , 0 , &dstRect , 0 , &srcRect , DISPMANX_PROTECTION_NONE , NULL , NULL , DISPMANX_NO_ROTATE ); s_dispmanWindow.element = dispmanElement; s_dispmanWindow.width = _width; s_dispmanWindow.height = _height; nwh = &s_dispmanWindow; vc_dispmanx_update_submit_sync(dispmanUpdate); # endif // BX_PLATFORM_ANDROID m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL); BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface."); const bool hasEglKhrCreateContext = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context"); const bool hasEglKhrNoError = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context_no_error"); for (uint32_t ii = 0; ii < 2; ++ii) { bx::StaticMemoryBlockWriter writer(s_contextAttrs, sizeof(s_contextAttrs) ); EGLint flags = 0; # if BX_PLATFORM_RPI BX_UNUSED(hasEglKhrCreateContext, hasEglKhrNoError); #else if (hasEglKhrCreateContext) { bx::write(&writer, EGLint(EGL_CONTEXT_MAJOR_VERSION_KHR) ); bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES / 10) ); bx::write(&writer, EGLint(EGL_CONTEXT_MINOR_VERSION_KHR) ); bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES % 10) ); flags |= BGFX_CONFIG_DEBUG && hasEglKhrNoError ? 0 | EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR : 0 ; if (0 == ii) { flags |= BGFX_CONFIG_DEBUG ? 0 | EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR // | EGL_OPENGL_ES3_BIT_KHR : 0 ; bx::write(&writer, EGLint(EGL_CONTEXT_FLAGS_KHR) ); bx::write(&writer, flags); } } else # endif // BX_PLATFORM_RPI { bx::write(&writer, EGLint(EGL_CONTEXT_CLIENT_VERSION) ); bx::write(&writer, 2); } bx::write(&writer, EGLint(EGL_NONE) ); m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, s_contextAttrs); if (NULL != m_context) { break; } BX_TRACE("Failed to create EGL context with EGL_CONTEXT_FLAGS_KHR (%08x).", flags); } BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context."); success = eglMakeCurrent(m_display, m_surface, m_surface, m_context); BGFX_FATAL(success, Fatal::UnableToInitialize, "Failed to set context."); m_current = NULL; eglSwapInterval(m_display, 0); } import(); }