簡體   English   中英

在OpenGL中使用持久性屏幕緩沖區來優化性能

[英]Using persistent screen buffer in OpenGL to optimize performance

我目前正在使用使用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()之類的函數,但還沒有弄清楚如何使它起作用。

因此,如果我想擁有2個繪圖層,其中一層始終保持不變,那么我應該如何操作緩沖區來做到這一點,從而最大化程序的性能呢?

如果您能根據我上面發布的內容提供示例代碼,我們將不勝感激!

是的,你可以這么做。 但是,除非您的渲染非常非常非常復雜,否則這種緩存通常不值得花時間實現。

它主要用於大屏幕分辨率和相對較慢的計算機,因此,盡管一切正常,但可以通過優化圖形來獲得一些性能提升。

我很確定,通過切換到現代OpenGL編程技術,您可以極大地提高性能。 例如,查找是否出現glBegin(…); … glEnd(); glBegin(…); … glEnd(); 塊: 擺脫那些,那些是性能殺手! 而是在頂點緩沖區對象中使用頂點數組 (或者,如果您不想使用現代OpenGL,也可以使用顯示列表 ,但是我建議不要使用它們)。

如果您真的想要在現代OpenGL中使用后台緩存,則使用幀緩沖對象非常容易。 創建一個“背景” FBO,在該FBO上附加一個顏色和一個深度模板渲染緩沖區。 然后,使用glBlitFramebuffer將背景圖像幀緩沖區復制到主幀緩沖區。

從技術上講,您可以通過此glClear操作來替換glClear ,但我建議您仍然在每個幀之前清除窗口幀緩沖區; 許多驅動程序將其用作暗示將要繪制新框架的提示,這可能會提高性能。 但是glClear的fillrate開銷也可能使情況變得更糟。

好的,我一直在研究用於存儲靜態背景的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重繪...)

我希望有使用緩沖區經驗的人可以在這里指出一些錯誤... :)我很確定它們一定很明顯。 我在這里沒有弄清楚所有正確的操作,可能只是在這里完全濫用了所有幀緩沖功能...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM