SDL_PollEvent()函数对渲染产生异常影响
SDL_PollEvent()函数对渲染产生异常影响
最近折腾SDL3的时候碰到个挺闹心的问题,想跟大伙唠唠。咱们都知道SDL3里屏幕坐标系的原点默认是在左上角的,这点本来没啥疑问。
我做了个简单测试:在一个最大化的窗口里,试着在原点位置渲染一个100x100的矩形,代码大概是这样的:
#include <SDL3/SDL.h> int main() { SDL_Window* window; SDL_Renderer* renderer; SDL_Init(SDL_INIT_VIDEO); SDL_CreateWindowAndRenderer("win", 800, 600, SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED); bool running = true; while (running) { SDL_Event event; // 问题就出在这行事件处理调用上 while (SDL_PollEvent(&event)) { if (event.type == SDL_EVENT_QUIT) { running = false; } } SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); SDL_Rect rect = {0, 0, 100, 100}; SDL_RenderFillRect(renderer, &rect); SDL_RenderPresent(renderer); } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
结果奇怪的事发生了:只要保留SDL_PollEvent()的调用,这个红色矩形就不在左上角了,明显偏移了一块;但要是把事件循环注释掉,渲染就完全正常,矩形乖乖待在左上角。
后来我琢磨明白原因了:SDL3在处理窗口事件(比如最大化后的状态变化)时,会自动调整渲染器的视口或者缩放系数,但这个变化在事件处理后没有同步到后续的渲染逻辑里。说白了就是,事件处理悄悄改了渲染的坐标系上下文,我没跟上调整。
给大伙两个可行的解决办法:
- 每次渲染前手动重置视口,确保坐标系和预期一致:
SDL_Rect viewport = {0, 0, 0, 0}; SDL_GetRendererOutputSize(renderer, &viewport.w, &viewport.h); SDL_SetRenderViewport(renderer, &viewport); - 专门处理窗口大小变化事件,在事件回调里更新渲染适配逻辑:
if (event.type == SDL_EVENT_WINDOW_RESIZED) { SDL_Rect viewport = {0, 0, event.window.data1, event.window.data2}; SDL_SetRenderViewport(renderer, &viewport); }
试了之后,不管有没有调用SDL_PollEvent(),矩形都能准确渲染在左上角了。说白了就是SDL3的事件处理和渲染状态绑定得更紧了,遇到这类问题多留意事件处理后渲染上下文的变化就行。
内容来源于stack exchange
相关产品推荐
相关产品推荐

