SDL2中如何实现窗口调整大小时同步调整窗口Surface?
解决SDL2窗口调整时SDL_Surface无法适配尺寸的问题
问题描述
我正在开发一款支持窗口调整的SDL2应用,但窗口尺寸改变时,对应的SDL_Surface并未随之调整。以下是复现问题的最小示例代码:
#include <SDL2/SDL.h> #include <iostream> int main(int argc, char **argv) { SDL_Init(SDL_INIT_VIDEO); SDL_Window *mainWindow = SDL_CreateWindow( "Debugging This", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 700, 400, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); SDL_Surface *mainWindowSurface = SDL_GetWindowSurface(mainWindow); int quit = 0; SDL_Event e; while (!quit) { while (SDL_PollEvent(&e)) { switch (e.type) { case SDL_QUIT: quit = 1; break; case SDL_WINDOWEVENT: if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { std::cout << "Window dimensions (w/h): " << e.window.data1 << "/" << e.window.data2 << "\n"; std::cout << "surface dimensions (w/h): " << mainWindowSurface->w << "/" << mainWindowSurface->h << "\n"; } break; } } SDL_FillRect(mainWindowSurface, NULL, SDL_MapRGB(mainWindowSurface->format, 0xFF, 0xFF, 0xFF)); SDL_UpdateWindowSurface(mainWindow); } SDL_FreeSurface(mainWindowSurface); mainWindowSurface = NULL; SDL_DestroyWindow(mainWindow); mainWindow = NULL; SDL_Quit(); return 0; }
运行程序调整窗口时,控制台输出的窗口尺寸正常变化,但Surface的尺寸始终保持初始值。由于需要频繁修改Surface,无法改用渲染器和纹理,请问如何实现窗口调整时Surface自动适配窗口大小?
解决方案
问题核心:窗口尺寸改变后,原有的SDL_Surface会失效,必须重新获取新的窗口Surface。SDL不会自动更新你之前保存的Surface指针,需要在窗口尺寸变化事件中手动更新。
修改后的代码如下:
#include <SDL2/SDL.h> #include <iostream> int main(int argc, char **argv) { SDL_Init(SDL_INIT_VIDEO); SDL_Window *mainWindow = SDL_CreateWindow( "Fixed Resize", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 700, 400, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); SDL_Surface *mainWindowSurface = SDL_GetWindowSurface(mainWindow); int quit = 0; SDL_Event e; while (!quit) { while (SDL_PollEvent(&e)) { switch (e.type) { case SDL_QUIT: quit = 1; break; case SDL_WINDOWEVENT: if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { // 释放旧的Surface,避免内存泄漏 SDL_FreeSurface(mainWindowSurface); // 重新获取适配新窗口尺寸的Surface mainWindowSurface = SDL_GetWindowSurface(mainWindow); // 验证新尺寸 std::cout << "Window dimensions (w/h): " << e.window.data1 << "/" << e.window.data2 << "\n"; std::cout << "surface dimensions (w/h): " << mainWindowSurface->w << "/" << mainWindowSurface->h << "\n"; } break; } } // 确保Surface有效再执行绘制操作 if (mainWindowSurface != nullptr) { SDL_FillRect(mainWindowSurface, NULL, SDL_MapRGB(mainWindowSurface->format, 0xFF, 0xFF, 0xFF)); SDL_UpdateWindowSurface(mainWindow); } } SDL_FreeSurface(mainWindowSurface); mainWindowSurface = NULL; SDL_DestroyWindow(mainWindow); mainWindow = NULL; SDL_Quit(); return 0; }
关键说明
- Surface失效机制:窗口尺寸改变时,SDL会销毁旧的窗口Surface并创建新的,之前保存的指针会指向无效内存,必须调用
SDL_GetWindowSurface重新获取新指针。 - 内存管理:每次resize时先释放旧Surface,退出时只需释放最后一次获取的Surface即可。
- 安全检查:添加
mainWindowSurface != nullptr判断,避免极端场景下的崩溃。
内容的提问来源于stack exchange,提问作者Stressed
相关产品推荐
相关产品推荐

