我目前正在开发一个使用2D OpenGL图形的Python程序。它主要用于大屏幕分辨率和相对较慢的计算机,因此,虽然它都可以正常工作,但它可以通过优化图形来获得一些性能提升。
所以这就是我所拥有的:屏幕背景是在程序启动时由多个图像组成的,之后永远不会改变。所以,我想知道是否可以将生成的屏幕数据写入缓冲区,然后在主绘图循环中不断使用,以绕过绘制背景所涉及的所有功能。
所以这就是我想做的事情:
def drawBackground(self): #Called once on startup
for item in BackObjects:
item.draw()
# [CODE HERE] Writing the screen pixel data to a buffer (a lower layer?)
def drawObjects(self): #Called in the main drawing loop
# [CODE HERE] Clear the buffer (possibly only the top layer?)
glLoadIdentity()
glPushMatrix()
# [CODE HERE] Read the previously defined background buffer to the screen?
for item in FrontObjects:
item.draw()
glPopMatrix()
glutSwapBuffers()
我已阅读有关缓冲区的不同GL函数的手册,并尝试使用glDrawBuffer()和glReadBuffer()之类的函数,但还没有弄清楚如何使其工作...... < / p>
所以,如果我想要有2个绘图层,其中一个始终保持不变,我应该如何操作缓冲区来实现这一点,最大化程序的性能?
如果您能根据我上面发布的内容提供示例代码,我将不胜感激!
答案 0 :(得分:0)
是的,你可以这样做。但是,除非您的呈现非常非常非常复杂,否则这种缓存通常不值得花时间来实现它。
它主要用于大屏幕分辨率和相对较慢的计算机,因此,虽然它都可以正常工作,但它可以通过优化图形来获得一些性能提升。
我很确定,通过切换到现代OpenGL编程技术,您可以大大提高性能。例如,查找glBegin(…); … glEnd();
块的任何出现:摆脱那些,那些是性能杀手!在顶点缓冲区对象中使用顶点数组 相反(或者你可以使用显示列表如果你不想使用现代OpenGL,但我建议不要使用它们。)
如果你真的想在现代OpenGL中使用后台缓存,那么使用framebuffer对象非常容易。创建一个“背景”FBO,您可以在其上附加颜色和深度模板渲染缓冲区。然后使用glBlitFramebuffer从背景图像帧缓冲区复制到主帧缓冲区。
从技术上讲,您可以通过此blitting操作替换glClear
,但我建议您在每帧之前仍然清除窗口帧缓冲;许多驱动程序使用它作为提示,即将绘制新帧,这可以提高性能。然而,glClear的填充费用也可能使事情变得更糟。
答案 1 :(得分:0)
好的,我一直在研究FrameBuffers存储静态背景,我似乎迷失在这里...... 这是我的背景生成和主绘图循环函数到目前为止的样子:
def MakeBackground(self):
self.BufferBack = glGenFramebuffers(1)
self.BufferRender = glGenRenderbuffers(1)
glBindRenderbuffer(GL_RENDERBUFFER, self.BufferRender)
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, self.ScreenWidth, self.ScreenHeight)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glPushMatrix()
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT)
for obj in BackObjects:
obj.drawBack()
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT)
glPopMatrix()
glBindFramebuffer(GL_FRAMEBUFFER, self.BufferBack)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, self.BufferRender)
glutSwapBuffers()
glBindRenderbuffer(GL_RENDERBUFFER, 0)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
def DrawCycle(self):
self.UpdatePositions()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glPushMatrix()
glBindFramebuffer(GL_FRAMEBUFFER, self.BufferBack)
glBlitFramebuffer(0,0,1920,1080,0,0,1920,1080,GL_COLOR_BUFFER_BIT,GL_LINEAR)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT)
for obj in FrontObjects:
obj.draw()
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT)
glPopMatrix()
glutPostRedisplay()
glutSwapBuffers()
我正在尝试在主绘图循环中绘制存储在“self.BufferBack”帧缓冲区中的背景。背景只是在第一帧中绘制(执行MakeBackground函数时),然后消失。也许是因为当执行glClear时帧缓冲被清除了?或者也许渲染的背景甚至没有存储在那里? (基于我在编辑glClear时看到的内容,背景不会被glBlitFramebuffer重新绘制...)
我希望有使用缓冲区的人可以在这里指出一些错误...... :)我很确定它们必须是显而易见的。我在这里没有想出所有正确的动作,可能只是完全滥用了所有的帧缓冲函数......