Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何编写SDL2/OpenGL事件循环_Python_Opengl_Sdl 2_Pyopengl_Pysdl2 - Fatal编程技术网

Python 如何编写SDL2/OpenGL事件循环

Python 如何编写SDL2/OpenGL事件循环,python,opengl,sdl-2,pyopengl,pysdl2,Python,Opengl,Sdl 2,Pyopengl,Pysdl2,我正在用Python中的SDL2和OpenGL(pysdl2,PyOpenGL)编写一个实时交互式图形应用程序。应用程序连续生成帧,这些帧可能会随着键盘/鼠标输入或时间的变化而变化 我的主事件循环是从网络上一些我无法再找到的模糊来源复制的,看起来(简化)如下: event = sdl2.SDL_Event() running = True while running: # process events while sdl2.SDL_PollEvent(ctypes.byref(e

我正在用Python中的SDL2和OpenGL(pysdl2,PyOpenGL)编写一个实时交互式图形应用程序。应用程序连续生成帧,这些帧可能会随着键盘/鼠标输入或时间的变化而变化

我的主事件循环是从网络上一些我无法再找到的模糊来源复制的,看起来(简化)如下:

event = sdl2.SDL_Event()
running = True
while running:
    # process events
    while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0:
        if event.type == sdl2.SDL_QUIT:
            running = False
    # render frame
    <some OpenGL commands>
    sdl2.SDL_GL_SwapWindow(window)
    sdl2.SDL_Delay(10)
event=sdl2.SDL_event()
运行=真
运行时:
#处理事件
而sdl2.SDL_PollEvent(ctypes.byref(event))!=0:
如果event.type==sdl2.SDL_退出:
运行=错误
#渲染帧
sdl2.SDL_GL_SwapWindow(窗口)
sdl2.SDL_延迟(10)
据我所知,10毫秒的延迟是为了给CPU一些喘息的空间,事实上,当我移除它时,CPU的使用率会翻倍

我不明白的是为什么这是必要的。图形显示为双缓冲,缓冲交换与垂直回程同步(60 Hz=16 ms)。天真地说,如果
所需时间少于16 ms,那么
SDL\u GL\u SwapWindow
无论如何都会引入延迟,因此
SDL\u延迟
是不必要的。如果他们使用的超过这些,那么程序就很难跟上显示帧速率,引入延迟将是有害的

现在,根据我在中被告知的,当执行
SDL\u GL\u SwapWindow
时,缓冲区交换和回溯同步不会发生,但这只会将一条“sync&swap”指令放入OpenGL队列中,并且在之前的所有操作完成后执行该指令。这同样适用于
。但是这个指令队列是有限的,因此在某个时刻,我的程序不会等待回溯,而是等待指令队列中有空间。最终的效果应该是一样的:如果我的事件循环的一次执行需要的平均时间少于16毫秒,那么程序的平均延迟时间将足以使每次循环执行16毫秒。那么,为什么需要明确的延迟呢


作为第二个问题:考虑到延迟可能会影响帧速率,有没有更好的方法让CPU休息?

可能是将帧速率限制在vsync一半的初始代码,我们真的不知道(不同的监视器具有不同的刷新率)。如果您想要完整的监视器刷新率,并且您有vsync,则不需要它。如果vsync被禁用(或者实现得不好),事情会变得更加复杂,但是简单的常量值延迟在这里不是一个解决方案(更不用说延迟不是很精确)。不过,我不明白第二个问题,这是两个相互矛盾的问题。@keltar,谢谢你,很抱歉回复得太晚。第二个问题与前面的观察结果有关:“据我所知,10毫秒的延迟是为了给CPU一些喘息的空间,事实上,当我移除它时,CPU使用率会加倍。”该程序不受CPU限制,CPU只是每帧发送几个OpenGL命令。并且帧速率由vsync控制(至60hz)。因此,无论如何,CPU应该主要在等待。不过,使用
SDL_Delay
可以减少报告的CPU使用量(在这种情况下,在不降低帧速率的情况下,显然CPU每帧所需的时间少于6毫秒)。我不明白,但似乎需要一些“给CPU一些喘息空间”的东西?也许
SDL_Delay
有隐式向操作系统调度程序发送信号的副作用?如果您确定仍然有60fps(30太容易解释)然后我会开始使用系统范围的探查器,比如linux上的perf/oprofile或windows上的ETW,以查看时间在哪里消耗。也许dirver认为下一个vsync的时间相对较短,并求助于spinlock,而不是OS调用延迟/重新调度。SDL_延迟不是一个自旋锁,因此它不使用CPU,但要求操作系统“暂停进程/线程至少一段时间”——对于某些任务来说太不精确。