2015-04-23 101 views
4

創建不能釋放紋理我遇到使用共享上下文的問題。 Ctx2創建與Ctx1共享。通過共享上下文

然後,在Thr2中,我創建了一些以Ctx2作爲當前上下文的紋理,並進行一些渲染。之後,我銷燬Ctx2並完成Thr2。

現在問題出現了:在我銷燬Ctx2之後,在Ctx2下創建的紋理沒有被釋放(一些然後,不是全部)。我使用gDebugger來剖析我的程式,並看到這些紋理並未發佈,並在Ctx1下列出。

當我重複創建Thr2/Ctx2並創建紋理並銷燬Thr2/Ctx2時,紋理越來越多,以及內存越來越多。

我曾嘗試:

刪除紋理THR2之前摧毀Ctx2;

在Thr2中,將Ctx1設置爲當前值,並在Ctx2被銷燬前嘗試刪除紋理;

回答

5

這聽起來像預期的行爲。

爲了解釋具有多個上下文的對象的生命週期,我將使用「池」一詞來描述一組紋理。我不認爲這個概念有通用的術語,所以這和任何東西都一樣好。

儘管您可能通常會對上下文擁有的紋理進行圖片處理,但實際上它們都屬於一個池。只要你有一個單一的背景,這是一個學術上的差異。上下文擁有該​​池,該池擁有在上下文中創建的所有紋理。當上下文被破壞時,游泳池就會消失,反過來會破壞游泳池中的所有紋理。

現在,有了兩個共享上下文,事情變得更有趣。您仍有一個池,這兩個上下文都具有共享所有權。當您在兩個上下文中的任何一個環境中創建紋理時,紋理都歸共享池所有。當上下文被刪除時,它放棄了共享池的所有權。只要至少有一個上下文處於活動狀態,該池(包括池中的所有紋理)就會保持不變。

在您的場景中,上下文2會創建紋理。此紋理添加到由上下文1和上下文2共享的池中。然後刪除上下文2.創建的紋理保留在池中。由於上下文1(仍然存在)共享池的所有權,因此池本身保持活動狀態。這意味着紋理也保持活躍。上下文2創建紋理是無關緊要的,因爲紋理歸池所有,而不是上下文2.

因此,如果您確實想要刪除紋理,則必須調用glDeleteTexture()。如果在上下文1或上下文2中進行此調用,則無關緊要。

刪除共享紋理時存在一些細微方面,例如與紋理爲FBO附件有關的問題,或與綁定時在一個上下文中被刪除的紋理在另一種情況下。但是由於這不是這個問題的核心,而且有點複雜,所以我會參考規範中的細節(例如參見OpenGL 3.3規範第337頁的D.1.2部分)。

+0

非常感謝。對不起,我是新來的OpenGL。在我的場景中,如果Thr2在調用MakeCurrent(0,0,0)後調用glDeleteTextures,會發生什麼?根據你所說的,似乎沒有什麼會發生。我對嗎? – CurtisGuo

+0

是的,您需要在擁有當前上下文的情況下進行所有OpenGL調用。否則他們不會有任何效果。 –

+0

如果(在GLX擴展中)glXMakeCurrent(dpy,0,0)被調用,並且GLXDrawable被銷燬。它是唯一的方法來刪除我創建一個新的GLXDrawable的紋理,並調用glXMakeCurrent(dpy,Ctx2,drawable)並刪除紋理? – CurtisGuo