我使用以下结构来获取调整大小的 SDL 窗口的新宽度和高度:
if (sdl_set->GetMainEvent()->type == SDL_WINDOWEVENT)
{
if (sdl_set->GetMainEvent()->window.event == SDL_WINDOWEVENT_RESIZED)
{
ScreenWidth = sdl_set->GetMainEvent()->window.data1;
ScreenHeight = sdl_set->GetMainEvent()->window.data2;
cout << "Window Resized!" << endl;
}
}
但是使用这种结构,我只能在调整大小完成后(即完成拖动并释放鼠标按钮时)获取新数据。
如何在拖动窗口时持续获取新数据?
static int resizingEventWatcher(void* data, SDL_Event* event) {
if (event->type == SDL_WINDOWEVENT &&
event->window.event == SDL_WINDOWEVENT_RESIZED) {
SDL_Window* win = SDL_GetWindowFromID(event->window.windowID);
if (win == (SDL_Window*)data) {
printf("resizing.....\n");
}
}
return 0;
}
int main() {
SDL_Window* win = ...
...
SDL_AddEventWatch(resizingEventWatcher, win);
...
}
使用SDL的EventWatch可以解决。
如果您使用单线程,则使用
SDL_AddEventWatch
设置事件观察器是不够的。这是因为 SDL_PumpEvents
(由 sdl 直接或间接调用)在调整大小完成之前不会返回,从而有效地阻塞了您的线程。
要解决此问题,您可以在事件观察器中设置回调:
void Window::HandleWindowEvent(const SDL_WindowEvent e)
{
switch(e.event)
{
...
case SDL_WINDOWEVENT_MOVED:
if (_lastWindowMetrics.left != e.data1 || _lastWindowMetrics.top != e.data2)
{
_lastWindowMetrics.left = e.data1;
_lastWindowMetrics.top = e.data2;
_windowEvents.emplace_back(_lastWindowMetrics);
_refresh(); // user callback that may be used to repaint the window
}
break;
case SDL_WINDOWEVENT_RESIZED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
if (_lastWindowMetrics.width != e.data1 || _lastWindowMetrics.height != e.data2)
{
_lastWindowMetrics.width = e.data1;
_lastWindowMetrics.height = e.data2;
_windowEvents.emplace_back(_lastWindowMetrics);
_refresh(); // user callback that may be used to repaint the window
}
break;
...
}
}
我使用观察者机制来处理所有窗口事件,并且只使用
SDL_PumpEvents
而不使用SDL_PollEvents
。
这与
glfwSetWindowRefreshCallback
提供的机制非常相似(如果你习惯了 glfw)。
使用 SDL3:
_Bool event_watch(void *userdata, SDL_Event *event) {
if (event->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) {
do_something();
}
return true;
}
int main() {
SDL_AddEventWatch(event_watch, NULL);
...
}
如果您使用的是 Windows,您是否尝试过使用 Windows api?
我知道这不是一个真正的解决方案,但如果您没有制作跨平台应用程序,您应该尝试一下。
使用HWND查找SDL的窗口并返回窗口大小。