void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) { #if SDL_VERSION_ATLEAST(2, 0, 0) // We sometime get outdated resize events from SDL2. So check that the size we get // is the actual current window size. If not ignore the resize. // The issue for example occurs when switching from fullscreen to windowed mode or // when switching between different fullscreen resolutions because SDL_DestroyWindow // for a fullscreen window that doesn't have the SDL_WINDOW_FULLSCREEN_DESKTOP flag // causes a SDL_WINDOWEVENT_RESIZED event with the old resolution to be sent, and this // event is processed after recreating the window at the new resolution. int currentWidth, currentHeight; getWindowDimensions(¤tWidth, ¤tHeight); if (width != (uint)currentWidth || height != (uint)currentHeight) return; setActualScreenSize(width, height); _eventSource->resetKeyboardEmulation(width - 1, height - 1); #else if (!_ignoreResizeEvents && _hwScreen && !(_hwScreen->flags & SDL_FULLSCREEN)) { // We save that we handled a resize event here. We need to know this // so we do not overwrite the users requested window size whenever we // switch aspect ratio or similar. _gotResize = true; if (!setupMode(width, height)) { warning("OpenGLSdlGraphicsManager::notifyResize: Resize failed ('%s')", SDL_GetError()); g_system->quit(); } } #endif }
result TizenGraphicsManager::Construct() { // Initialize our OpenGL ES context. loadEgl(); // Notify the OpenGL code about our context. // We default to RGB565 and RGBA5551 which is closest to the actual output // mode we setup. notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)); // Tell our size. int x, y, width, height; _appForm->GetBounds(x, y, width, height); AppLog("screen size: %dx%d", width, height); setActualScreenSize(width, height); return E_SUCCESS; }
void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) { // Initialize all extensions. initializeGLExtensions(); // Disable 3D properties. GLCALL(glDisable(GL_CULL_FACE)); GLCALL(glDisable(GL_DEPTH_TEST)); GLCALL(glDisable(GL_LIGHTING)); GLCALL(glDisable(GL_FOG)); GLCALL(glDisable(GL_DITHER)); GLCALL(glShadeModel(GL_FLAT)); GLCALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)); // Default to black as clear color. GLCALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f)); // Setup alpha blend (for overlay and cursor). GLCALL(glEnable(GL_BLEND)); GLCALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); // Enable rendering with vertex and coord arrays. GLCALL(glEnableClientState(GL_VERTEX_ARRAY)); GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY)); GLCALL(glEnable(GL_TEXTURE_2D)); // We use a "pack" alignment (when reading from textures) to 4 here, // since the only place where we really use it is the BMP screenshot // code and that requires the same alignment too. GLCALL(glPixelStorei(GL_PACK_ALIGNMENT, 4)); // Query information needed by textures. Texture::queryTextureInformation(); // Refresh the output screen dimensions if some are set up. if (_outputScreenWidth != 0 && _outputScreenHeight != 0) { setActualScreenSize(_outputScreenWidth, _outputScreenHeight); } // TODO: Should we try to convert textures into one of those formats if // possible? For example, when _gameScreen is CLUT8 we might want to use // defaultFormat now. _defaultFormat = defaultFormat; _defaultFormatAlpha = defaultFormatAlpha; if (_gameScreen) { _gameScreen->recreateInternalTexture(); } if (_overlay) { _overlay->recreateInternalTexture(); } if (_cursor) { _cursor->recreateInternalTexture(); } #ifdef USE_OSD if (_osd) { _osd->recreateInternalTexture(); } #endif }
bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { // In case we request a fullscreen mode we will use the mode the user // has chosen last time or the biggest mode available. if (_wantsFullScreen) { if (_desiredFullscreenWidth && _desiredFullscreenHeight) { // In case only a distinct set of modes is available we check // whether the requested mode is actually available. if (!_fullscreenVideoModes.empty()) { VideoModeArray::const_iterator i = Common::find(_fullscreenVideoModes.begin(), _fullscreenVideoModes.end(), VideoMode(_desiredFullscreenWidth, _desiredFullscreenHeight)); // It's not available fall back to default. if (i == _fullscreenVideoModes.end()) { _desiredFullscreenWidth = 0; _desiredFullscreenHeight = 0; } } } // In case no desired mode has been set we default to the biggest mode // available or the requested mode in case we don't know any // any fullscreen modes. if (!_desiredFullscreenWidth || !_desiredFullscreenHeight) { if (!_fullscreenVideoModes.empty()) { VideoModeArray::const_iterator i = _fullscreenVideoModes.end(); --i; _desiredFullscreenWidth = i->width; _desiredFullscreenHeight = i->height; } else { _desiredFullscreenWidth = width; _desiredFullscreenHeight = height; } } // Remember our choice. ConfMan.setInt("last_fullscreen_mode_width", _desiredFullscreenWidth, Common::ConfigManager::kApplicationDomain); ConfMan.setInt("last_fullscreen_mode_height", _desiredFullscreenHeight, Common::ConfigManager::kApplicationDomain); // Use our choice. width = _desiredFullscreenWidth; height = _desiredFullscreenHeight; } // This is pretty confusing since RGBA8888 talks about the memory // layout here. This is a different logical layout depending on // whether we run on little endian or big endian. However, we can // only safely assume that RGBA8888 in memory layout is supported. // Thus, we chose this one. const Graphics::PixelFormat rgba8888 = #ifdef SCUMM_LITTLE_ENDIAN Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24); #else Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); #endif #if SDL_VERSION_ATLEAST(2, 0, 0) if (_glContext) { notifyContextDestroy(); SDL_GL_DeleteContext(_glContext); _glContext = nullptr; } _window->destroyWindow(); uint32 flags = SDL_WINDOW_OPENGL; if (_wantsFullScreen) { flags |= SDL_WINDOW_FULLSCREEN; } else { flags |= SDL_WINDOW_RESIZABLE; } // Request a OpenGL (ES) context we can use. SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, _glContextProfileMask); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, _glContextMajor); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, _glContextMinor); if (!_window->createWindow(width, height, flags)) { // We treat fullscreen requests as a "hint" for now. This means in // case it is not available we simply ignore it. if (_wantsFullScreen) { _window->createWindow(width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); } if (!_window->getSDLWindow()) { return false; } } _glContext = SDL_GL_CreateContext(_window->getSDLWindow()); if (!_glContext) { return false; } notifyContextCreate(rgba8888, rgba8888); int actualWidth, actualHeight; getWindowDimensions(&actualWidth, &actualHeight); setActualScreenSize(actualWidth, actualHeight); _eventSource->resetKeyboardEmulation(actualWidth - 1, actualHeight - 1); return true; #else // WORKAROUND: Working around infamous SDL bugs when switching // resolutions too fast. This might cause the event system to supply // incorrect mouse position events otherwise. // Reference: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=665779 const uint32 curTime = SDL_GetTicks(); if (_hwScreen && (curTime < _lastVideoModeLoad || curTime - _lastVideoModeLoad < 100)) { for (int i = 10; i > 0; --i) { SDL_PumpEvents(); SDL_Delay(10); } } uint32 flags = SDL_OPENGL; if (_wantsFullScreen) { flags |= SDL_FULLSCREEN; } else { flags |= SDL_RESIZABLE; } if (_hwScreen) { // When a video mode has been setup already we notify the manager that // the context is about to be destroyed. // We do this because on Windows SDL_SetVideoMode can destroy and // recreate the OpenGL context. notifyContextDestroy(); } _hwScreen = SDL_SetVideoMode(width, height, 32, flags); if (!_hwScreen) { // We treat fullscreen requests as a "hint" for now. This means in // case it is not available we simply ignore it. if (_wantsFullScreen) { _hwScreen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL | SDL_RESIZABLE); } } // Part of the WORKAROUND mentioned above. _lastVideoModeLoad = SDL_GetTicks(); if (_hwScreen) { notifyContextCreate(rgba8888, rgba8888); setActualScreenSize(_hwScreen->w, _hwScreen->h); _eventSource->resetKeyboardEmulation(_hwScreen->w - 1, _hwScreen->h - 1); } // Ignore resize events (from SDL) for a few frames, if this isn't // caused by a notification from SDL. This avoids bad resizes to a // (former) resolution for which we haven't processed an event yet. if (!_gotResize) _ignoreResizeEvents = 10; return _hwScreen != nullptr; #endif }
void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) { // Initialize context for use. initializeGLContext(); // Initialize pipeline. delete _pipeline; _pipeline = nullptr; #if !USE_FORCED_GLES if (g_context.shadersSupported) { ShaderMan.notifyCreate(); _pipeline = new ShaderPipeline(ShaderMan.query(ShaderManager::kDefault)); } #endif #if !USE_FORCED_GLES2 if (_pipeline == nullptr) { _pipeline = new FixedPipeline(); } #endif g_context.setPipeline(_pipeline); // Disable 3D properties. GL_CALL(glDisable(GL_CULL_FACE)); GL_CALL(glDisable(GL_DEPTH_TEST)); GL_CALL(glDisable(GL_DITHER)); g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f); GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); // Setup backbuffer state. // Default to black as clear color. _backBuffer.setClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Setup alpha blend (for overlay and cursor). _backBuffer.enableBlend(true); // Setup scissor state accordingly. _backBuffer.enableScissorTest(!_overlayVisible); g_context.getActivePipeline()->setFramebuffer(&_backBuffer); // Clear the whole screen for the first three frames to assure any // leftovers are cleared. _scissorOverride = 3; // We use a "pack" alignment (when reading from textures) to 4 here, // since the only place where we really use it is the BMP screenshot // code and that requires the same alignment too. GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4)); // Refresh the output screen dimensions if some are set up. if (_outputScreenWidth != 0 && _outputScreenHeight != 0) { setActualScreenSize(_outputScreenWidth, _outputScreenHeight); } // TODO: Should we try to convert textures into one of those formats if // possible? For example, when _gameScreen is CLUT8 we might want to use // defaultFormat now. _defaultFormat = defaultFormat; _defaultFormatAlpha = defaultFormatAlpha; if (_gameScreen) { _gameScreen->recreate(); } if (_overlay) { _overlay->recreate(); } if (_cursor) { _cursor->recreate(); } #ifdef USE_OSD if (_osdMessageSurface) { _osdMessageSurface->recreate(); } if (_osdIconSurface) { _osdIconSurface->recreate(); } #endif }
bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { // In case we request a fullscreen mode we will use the mode the user // has chosen last time or the biggest mode available. if (_wantsFullScreen) { if (_desiredFullscreenWidth && _desiredFullscreenHeight) { // In case only a distinct set of modes is available we check // whether the requested mode is actually available. if (!_fullscreenVideoModes.empty()) { VideoModeArray::const_iterator i = Common::find(_fullscreenVideoModes.begin(), _fullscreenVideoModes.end(), VideoMode(_desiredFullscreenWidth, _desiredFullscreenHeight)); // It's not available fall back to default. if (i == _fullscreenVideoModes.end()) { _desiredFullscreenWidth = 0; _desiredFullscreenHeight = 0; } } } // In case no desired mode has been set we default to the biggest mode // available or the requested mode in case we don't know any // any fullscreen modes. if (!_desiredFullscreenWidth || !_desiredFullscreenHeight) { if (!_fullscreenVideoModes.empty()) { VideoModeArray::const_iterator i = _fullscreenVideoModes.end(); --i; _desiredFullscreenWidth = i->width; _desiredFullscreenHeight = i->height; } else { _desiredFullscreenWidth = width; _desiredFullscreenHeight = height; } } // Remember our choice. ConfMan.setInt("last_fullscreen_mode_width", _desiredFullscreenWidth, Common::ConfigManager::kApplicationDomain); ConfMan.setInt("last_fullscreen_mode_height", _desiredFullscreenHeight, Common::ConfigManager::kApplicationDomain); // Use our choice. width = _desiredFullscreenWidth; height = _desiredFullscreenHeight; } // WORKAROUND: Working around infamous SDL bugs when switching // resolutions too fast. This might cause the event system to supply // incorrect mouse position events otherwise. // Reference: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=665779 const uint32 curTime = SDL_GetTicks(); if (_hwScreen && (curTime < _lastVideoModeLoad || curTime - _lastVideoModeLoad < 100)) { for (int i = 10; i > 0; --i) { SDL_PumpEvents(); SDL_Delay(10); } } _lastVideoModeLoad = curTime; uint32 flags = SDL_OPENGL; if (_wantsFullScreen) { flags |= SDL_FULLSCREEN; } else { flags |= SDL_RESIZABLE; } _hwScreen = SDL_SetVideoMode(width, height, 32, flags); if (!_hwScreen) { // We treat fullscreen requests as a "hint" for now. This means in // case it is not available we simply ignore it. if (_wantsFullScreen) { _hwScreen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL | SDL_RESIZABLE); } } if (_hwScreen) { const Graphics::PixelFormat rgba8888 = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); notifyContextChange(rgba8888, rgba8888); setActualScreenSize(_hwScreen->w, _hwScreen->h); } return _hwScreen != nullptr; }