| Summary: | SDL_SetWindowDisplayMode changes display mode, but not the window size. | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Taavi Teemaa <taavi.teemaa> |
| Component: | video | Assignee: | Sam Lantinga <slouken> |
| Status: | NEW --- | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | ||
| Version: | 2.0.12 | ||
| Hardware: | x86_64 | ||
| OS: | Windows 10 | ||
The documentation says: "Fullscreen windows automatically match the size of the display mode, and you should use SDL_SetWindowDisplayMode() to change their size." Example code at the bottom. But when I call the function I see that the actual display mode is changed, but the window size or OpenGL backbuffer size doesn't change, UNTIL I go to the desktop and open the window again. SDL_WINDOWEVENT_SIZE_CHANGED event is also received only after this. I use SDL only for creating window and input handling. I first noticed the problem when implementing resolution change to my game and when I changed to a resolution with a different height. I got a black bar on top. I checked with RenderDoc and saw that the backbuffer was still actually the same and I was drawing to the bottom left corner of it with the new viewport and because the actual screen resolution was changed it only showed the top left of the backbuffer. I managed to recreate the problem with a small application. You can't see anything visually in this, because the clear clears the whole backbuffer, but the std::cout prints the current resolution of the window. And it only updates to the new resolution when I go to desktop and reopen the window. Workaround is that I call SDL_SetWindowSize() right after the SDL_SetWindowDisplayMode(). Then the size changes immediately. #include "SDL.h" #include <iostream> #include <vector> int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_EVERYTHING); int current_display_mode = 0; std::vector<SDL_DisplayMode> display_modes; // Fetch display modes with desktop pixel format and refresh rate { SDL_DisplayMode desktop_display_mode; SDL_GetDesktopDisplayMode(0, &desktop_display_mode); auto used_pixel_format = desktop_display_mode.format; auto used_refresh_rate = desktop_display_mode.refresh_rate; SDL_DisplayMode display_mode; auto num_display_modes = SDL_GetNumDisplayModes(0); for (auto i = 0; i < num_display_modes; ++i) { SDL_GetDisplayMode(0, i, &display_mode); if (display_mode.format != used_pixel_format) continue; if (display_mode.refresh_rate != used_refresh_rate) continue; display_modes.push_back(display_mode); } } SDL_Window* window = SDL_CreateWindow( "title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, display_modes[current_display_mode].w, display_modes[current_display_mode].h, SDL_WINDOW_FULLSCREEN); SDL_SetWindowDisplayMode(window, &display_modes[current_display_mode]); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); bool running = true; while (running) { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) running = false; if (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_D) { current_display_mode = (current_display_mode + 1) % display_modes.size(); auto& mode = display_modes[current_display_mode]; SDL_SetWindowDisplayMode(window, &mode); } if (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) running = false; } if (!running) break; SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); SDL_Delay(100); int dims[2]; SDL_GetWindowSize(window, dims, dims + 1); std::cout << dims[0] << " " << dims[1] << std::endl; } SDL_Quit(); return 0; }