2016-08-01 96 views
4

我最近从https://github.com/fogleman/Craft下载了fogleman的优秀“500行Minecraft”演示。我使用了2to3工具,并手动更正了一些细节,使它可以在python3下运行。我现在想着在render方法中调用self.clear()的一件事。这是被称为pyglet每帧我修改渲染方法:Python我的世界pyglet glClear()跳过帧

def on_draw(self): 
    """ Called by pyglet to draw the canvas. 

    """ 
    frameStart = time.time() 
    self.clear() 
    clearTime = time.time() 
    self.set_3d() 
    glColor3d(1, 1, 1) 
    self.model.batch.draw() 
    self.draw_focused_block() 
    self.set_2d() 
    self.draw_label() 
    self.draw_reticle() 
    renderTime = time.time() 

    self.clearBuffer.append(str(clearTime - frameStart)) 
    self.renderBuffer.append(str(renderTime - clearTime)) 

正如你所看到的,我参加了self.clear()的执行时间和渲染方法的其余部分。的self.clear()电话pyglet的这种方法的调用,可以在.../pyglet /窗/ __ init__.py发现:

def clear(self): 
    '''Clear the window. 

    This is a convenience method for clearing the color and depth 
    buffer. The window must be the active context (see `switch_to`). 
    ''' 
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 

所以我基本上做作出glClear()通话。
我在测试游戏时发现了一些帧丢失(以60 FPS),所以我添加了上面的代码来测量命令的执行时间,尤其是glClear()。我发现渲染本身永远不会超过10毫秒。但glClear()时间是有点不同的故事,这里是在不同条件下的3个测量分布:
Duration of glClear() under different conditions.

品红色线显示一帧的时间限制。因此,第一行后面的所有内容都意味着有一帧丢失。
glClear()的执行时间在第一帧到期后似乎有某种“回声”。你能解释我为什么吗?我怎样才能更快地打电话?
不幸的是我不是OpenGL的专家,所以我很感谢每个建议家伙。 ;)

+1

这可能是您的计时器分辨率仅为16毫秒,这将解释“回声”。请参阅https://docs.python.org/2/library/time.html#time.time,其中指出“并非所有系统的时间精度都超过1秒”。尝试一个不同的计时器,看看它是否重要。 – TWT

回答

0

你的图表是错误的。那么,至少它不适合测量性能的图表。永远不要相信gl*函数在你告诉它时执行,并且永远不要相信它执行得如你所期望的那样快。

大多数gl*函数不会马上执行,它们不可能是。记住,我们正在处理GPU,告诉它直接做东西很慢。因此,我们为GPU编写待办事项列表(命令队列),并在我们需要GPU输出内容时,将其转储到VRAM中。这个“转储”是一个称为同步的过程的一部分,我们可以用glFlush来触发。虽然,OpenGL是用户友好的(至少与Vulkan相比),因此它不依赖于我们显式地刷新命令队列。很多gl*函数(完全取决于您的图形驱动程序)将隐式地同步CPU和GPU状态,其中包括刷新。

由于glClear通常会启动一个帧,因此您的驱动程序可能认为执行这种隐式同步会很好。正如你可能想象的,同步是一个非常缓慢的过程,并阻止CPU执行,直到完成。

而这可能是这里发生了什么。部分同步过程是执行内存事务(例如glBufferData,glTexImage*),这些事务可能会排队等待直到它们被您的glClear调用刷新。在你的例子中,这是有道理的;我们可以观察到的尖峰可能是您上传了大量区块数据后的帧。

但请记住,这只是纯粹的猜测,我也不是这方面的专家,所以不要相信我的确切细节。OpenGL wiki上的This page是这类事情的很好资源。

虽然有一件事是确定的,但只要您的配置文件声称您的glClear调用不会发生。您应该使用专用于分析图形的分析器。