【问题标题】:SDL_PollEvent indepthSDL_PollEvent 深入
【发布时间】:2014-02-21 21:15:08
【问题描述】:

这是SDL2代码的一部分

SDL 主函数

int main(int argc,char *argv[])
{
     ...
     ...
     bool quit=false;
     SDL_Event e;
     while(!quit)  ///First while (say)
     {
            while(SDL_PollEvent(&e)) ///Second while (say)
            {
                if(e.type==SDL_QUIT)
                {
                    quit=true;
                }
                handleEvent(e) ;///Function for executing certain event
            }

            ...
            SDL_RenderPresent((SDL_Renderer)renderer);
     }

  }

我的问题是,这个 SDL_PollEvent() 实际上是做什么的,假设一个事件发生了,执行是否在第二个 while() 之后调用 SDL_RenderPresent() 或者它等待所有事件进行轮询然后SDL_RenderPresent() 被调用,我完全糊涂了?

【问题讨论】:

    标签: c++ sdl


    【解决方案1】:

    以上是一个很常见的单线程事件循环:

    基本上,应用程序始终位于外部 while 循环中。为了获得最流畅的用户体验,我们尝试将此循环保持在 17 毫秒以下(对于每秒 60 帧的速率)

    每个“帧”都从响应队列中等待的所有事件开始(内部 while):

            while(SDL_PollEvent(&e)) ///Second while (say)
            {
                if(e.type==SDL_QUIT)
                {
                    quit=true;
                }
                handleEvent(e) ;///Function for executing certain event
            }
    

    事件是来自操作系统的通知,表示发生了某些事情。可能是窗口正在关闭 SDL_QUIT 或鼠标已移动。 您必须响应这些事件才能使应用程序响应。通常响应是改变应用程序的状态。

    例如,我们可能会看到 left-mouse is down 事件,我们可能会发现鼠标按钮“下方”的内容并指示它现在已被选中。这通常只是找到对象并调用将更改其状态的函数。改变的只是布尔值,表明对象现在已被选中。

    也许移动鼠标需要改变下一帧的视角,所以我们将更新存储我们正在查看的方向的向量。所以我们更新内存中的向量。

    在事件队列为空且应用程序没有任何事件要处理的情况下,您可能会遇到很长一段时间。并且可能会有一连串的活动(例如用户移动鼠标),您会得到很多要响应的事件。

    SDL_PollEvent 不会“等待”事件。如果队列中有事件,您将获得信息。如果没有事件,它将返回 false。
    处理事件应该很快完成(记住我们必须在 17 毫秒内完成)不要担心这在 PC 上是相当多的时间。

    完成所有事件并退出内部循环后,您就可以继续更新世界和渲染了。 在这一点上,你通常会做人工智能之类的事情。调用物理引擎。例如,您可能会遍历对象并根据它们的速度更改它们的位置。

    下一步是实际绘制。

            SDL_RenderClear(renderer);
            ...
            SDL_RenderPresent((SDL_Renderer)renderer);
    

    第一次调用将清除屏幕。然后,您可以根据不同对象的状态进行渲染。例如,可能是因为我们将对象状态更改为选中,我们现在将在它周围绘制一个发光的边框。

    您的最终调用是让 SDL_RenderPresent(renderer) 向用户呈现新屏幕

    如果您使用的是 Vsync(很常见),那么这个最终调用将隐藏一小段等待时间,以将屏幕更新与显卡功能同步。这将产生更平滑的图形。假设刷新率为 60Hz(每秒 60 帧)并假设您在帧渲染逻辑中运行的时间低于 16.6 毫秒,应用程序将等待剩余时间。

    现在应用程序准备好回到循环的开始并检查 SDL_PollEvent 中是否有任何事件。由于整个循环通常只需要几毫秒,因此应用程序将始终感到响应。

    【讨论】:

    • 这是不是这个意思,假设我想在这一秒内执行 10 个事件,而循环这些事件将存储在事件队列中并制作相应的帧,并且在第 11 个为空的事件 SDL_PollEvent() 将return false 并退出第二个 while 循环,所有十帧都使用 SDL_RenderPresent() 在屏幕上渲染,它是这样工作的吗?
    • 你不'执行'事件..你回应他们。它们表明操作系统中发生了某些事情(窗口大小调整/鼠标移动)。如果您不回复他们,应用程序将似乎没有响应。一旦你回复了所有这些,你就会回到绘制下一帧
    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多