EglContext::EglContext(EglContext* shared) : m_display (EGL_NO_DISPLAY), m_context (EGL_NO_CONTEXT), m_surface (EGL_NO_SURFACE), m_config (NULL) { // Get the initialized EGL display m_display = getInitializedDisplay(); // Get the best EGL config matching the default video settings m_config = getBestConfig(m_display, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); updateSettings(); // Note: The EGL specs say that attrib_list can be NULL when passed to eglCreatePbufferSurface, // but this is resulting in a segfault. Bug in Android? EGLint attrib_list[] = { EGL_WIDTH, 1, EGL_HEIGHT,1, EGL_NONE }; m_surface = eglCheck(eglCreatePbufferSurface(m_display, m_config, attrib_list)); // Create EGL context createContext(shared); }
bool EglContext::makeCurrent(bool current) { if (current) return m_surface != EGL_NO_SURFACE && eglCheck(eglMakeCurrent(m_display, m_surface, m_surface, m_context)); return m_surface != EGL_NO_SURFACE && eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); }
void WindowImpl::handleSurfaceCreation() { const EGLint surfaceAttribs[] = { JOP_CHECK_EGL_EXTENSION(EGL_KHR_gl_colorspace) ? EGL_VG_COLORSPACE : EGL_NONE, EGL_VG_COLORSPACE_sRGB, EGL_NONE }; auto state = detail::ActivityState::get(); auto win = state->window; if (win && win->m_surface == EGL_NO_SURFACE) { win->m_surface = eglCheck(eglCreateWindowSurface(getDisplay(), win->m_config, state->nativeWindow, surfaceAttribs)); JOP_ASSERT(win->m_surface != EGL_NO_SURFACE, "Failed to create window surface!"); if (win->m_context != EGL_NO_CONTEXT) { EGLBoolean success = eglCheck(eglMakeCurrent(getDisplay(), win->m_surface, win->m_surface, win->m_context)); JOP_ASSERT(success == EGL_TRUE, "Failed to make context current!"); } if (win->m_fullScreen) goFullscreen(); updateSize(win->m_size, win->m_surface); } }
void EglContext::destroySurface() { eglCheck(eglDestroySurface(m_display, m_surface)); m_surface = EGL_NO_SURFACE; // Ensure that this context is no longer active since our surface is now destroyed setActive(false); }
void EglContext::updateSettings() { EGLint tmp; // Update the internal context settings with the current config eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_DEPTH_SIZE, &tmp)); m_settings.depthBits = tmp; eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_STENCIL_SIZE, &tmp)); m_settings.stencilBits = tmp; eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_SAMPLES, &tmp)); m_settings.antialiasingLevel = tmp; m_settings.majorVersion = 1; m_settings.minorVersion = 1; m_settings.attributeFlags = ContextSettings::Default; }
void WindowImpl::handleSurfaceDestruction() { auto state = detail::ActivityState::get(); auto win = state->window; if (win && win->m_surface != EGL_NO_SURFACE) { eglCheck(eglDestroySurface(getDisplay(), win->m_surface)); win->m_surface = EGL_NO_SURFACE; } }
EglContext::~EglContext() { // Deactivate the current context EGLContext currentContext = eglCheck(eglGetCurrentContext()); if (currentContext == m_context) { eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); } // Destroy context if (m_context != EGL_NO_CONTEXT) { eglCheck(eglDestroyContext(m_display, m_context)); } // Destroy surface if (m_surface != EGL_NO_SURFACE) { eglCheck(eglDestroySurface(m_display, m_surface)); } }
XVisualInfo EglContext::selectBestVisual(::Display* XDisplay, unsigned int bitsPerPixel, const ContextSettings& settings) { // Get the initialized EGL display EGLDisplay display = getInitializedDisplay(); // Get the best EGL config matching the default video settings EGLConfig config = getBestConfig(display, bitsPerPixel, settings); // Retrieve the visual id associated with this EGL config EGLint nativeVisualId; eglCheck(eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId)); if (nativeVisualId == 0) { // Should never happen... err() << "No EGL visual found. You should check your graphics driver" << std::endl; return XVisualInfo(); } XVisualInfo vTemplate; vTemplate.visualid = static_cast<VisualID>(nativeVisualId); // Get X11 visuals compatible with this EGL config XVisualInfo *availableVisuals, bestVisual; int visualCount = 0; availableVisuals = XGetVisualInfo(XDisplay, VisualIDMask, &vTemplate, &visualCount); if (visualCount == 0) { // Can't happen... err() << "No X11 visual found. Bug in your EGL implementation ?" << std::endl; return XVisualInfo(); } // Pick up the best one bestVisual = availableVisuals[0]; XFree(availableVisuals); return bestVisual; }
void EglContext::createContext(EglContext* shared) { const EGLint contextVersion[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; EGLContext toShared; if (shared) toShared = shared->m_context; else toShared = EGL_NO_CONTEXT; if (toShared != EGL_NO_CONTEXT) eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); // Create EGL context m_context = eglCheck(eglCreateContext(m_display, m_config, toShared, contextVersion)); }
EGLConfig EglContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixel, const ContextSettings& settings) { // Set our video settings constraint const EGLint attributes[] = { EGL_BUFFER_SIZE, bitsPerPixel, EGL_DEPTH_SIZE, settings.depthBits, EGL_STENCIL_SIZE, settings.stencilBits, EGL_SAMPLE_BUFFERS, settings.antialiasingLevel, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE }; EGLint configCount; EGLConfig configs[1]; // Ask EGL for the best config matching our video settings eglCheck(eglChooseConfig(display, attributes, configs, 1, &configCount)); // TODO: This should check EGL_CONFORMANT and pick the first conformant configuration. return configs[0]; }
void EglContext::createSurface(EGLNativeWindowType window) { m_surface = eglCheck(eglCreateWindowSurface(m_display, m_config, window, NULL)); }
void EglContext::setVerticalSyncEnabled(bool enabled) { eglCheck(eglSwapInterval(m_display, enabled ? 1 : 0)); }
void EglContext::display() { if (m_surface != EGL_NO_SURFACE) eglCheck(eglSwapBuffers(m_display, m_surface)); }
BOOL init( void ) { const SDL_VideoInfo *info = NULL; int depth; int flags; load_options(); if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK ) < 0 ) { fprintf( stderr, "SDL says: %s\n", SDL_GetError() ); return FALSE; } joy = SDL_JoystickOpen( 0 ); if( joy ) SDL_JoystickEventState( SDL_ENABLE ); // printf( "%p\n", joy ); needquit = TRUE; depth = 32; if( (info = SDL_GetVideoInfo()) ) depth = info->vfmt->BitsPerPixel; #ifdef __amigaos4__ printf( "Detected MiniGL v%d.%d\n", MiniGLBase->lib_Version, MiniGLBase->lib_Revision ); if( ( MiniGLBase->lib_Version < 2 ) || ( ( MiniGLBase->lib_Version == 2 ) && ( MiniGLBase->lib_Revision < 1 ) ) ) { //screenbodge = TRUE; printf( "WARNING: The video screen won't work properly on the spaceship level\n" ); printf( "with this version on MiniGL.\n" ); } #endif #ifdef HAVE_GLES flags = 0; #else flags = SDL_OPENGL; #endif #ifndef PANDORA if( fullscreen ) #endif flags |= SDL_FULLSCREEN; #ifdef PANDORA ssrf = SDL_SetVideoMode( 800, 480, depth, flags ); #else ssrf = SDL_SetVideoMode( WINWIDTH, WINHEIGHT, depth, flags ); #endif if( ssrf == 0 ) { fprintf( stderr, "SDL says: %s\n", SDL_GetError() ); return FALSE; } SDL_ShowCursor( SDL_DISABLE ); #ifdef HAVE_GLES // create EGL context // *TODO* : real egl Checking for error #define eglCheck() FALSE eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY); // Initialise EGL EGLint maj, min; if (!eglInitialize(eglDisplay, &maj, &min)) { fprintf( stderr, "EGL Error: eglInitialize failed\n"); return FALSE; } EGLint pi32ConfigAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT , EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_NONE }; EGLint pi32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1 , EGL_NONE }; int num_config; EGLConfig config; if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &config, 1, &num_config) || (num_config != 1)) { fprintf(stderr, "EGL Error: eglChooseConfig failed\n"); return FALSE; } eglSurface = eglCreateWindowSurface(eglDisplay, config, NULL, NULL); if (eglCheck()) return FALSE; eglBindAPI(EGL_OPENGL_ES_API); if (eglCheck()) return FALSE; eglContext = eglCreateContext(eglDisplay, config, NULL, pi32ContextAttribs); if (eglCheck()) return FALSE; eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); if (eglCheck()) return FALSE; EGLint w,h; eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w); eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h); // now, setup viewport to adapt to the surface //*TODO* adjust if surface is smaller int dx = (w-WINWIDTH)/2; int dy = (h-WINHEIGHT)/2; glViewport(dx, dy, WINWIDTH, WINHEIGHT); #endif /* #ifdef __amigaos4__ if( screenbodge ) { struct IntuitionBase *ibase = (struct IntuitionBase *)IntuitionBase; win = ibase->ActiveWindow; if( !win ) screenbodge = FALSE; } #endif */ // initialize sdl mixer, open up the audio device if( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 2048 ) < 0 ) { fprintf( stderr, "SDL_Mixer says: %s\n", Mix_GetError() ); } else { audioavailable = TRUE; } loadsounds(); if( !render_init() ) return FALSE; titlestate = 0; what_are_we_doing = WAWD_TITLES; return TRUE; }