在OpenGL中,glAttachShader
的訂購無關緊要,這是否與glDeleteShader
相同?如果有一些動態內存分配正在進行,我會說是,但也許這在opengl上下文中是不同的。glDeleteShader - 命令是不相關的嗎?
回答
不,您刪除着色器的順序是主要是不重要。
我說的主要是因爲在附加到GLSL程序並鏈接GLSL程序之前刪除着色器沒什麼意義。然而,一旦程序被鏈接,你可以做任何你想要的着色器。
OpenGL中的對象刪除由驅動程序處理,並不一定立即發生。它必須以這種方式工作,因爲OpenGL可能會對仍然引用您要刪除的對象的命令進行排隊。如果它立即刪除它們,那麼已經發布但尚未完成的命令將會有未定義的結果。相反,GL會在某個時間刪除對象內存之後,如果沒有其他人持有引用,則調用glDelete* (...)
。
當您撥打glDelete* (..)
時,GL立即執行的唯一操作是釋放對象名稱,以便glGen* (...)
命令重新使用(並從當前上下文中解除綁定)。內存回收不會發生,直到將來某個時候。
是 - 着色器可以按您喜歡的任何順序刪除。 Create
/Delete
遵循與原始內存塊相同的語義,如malloc
/free
。
不要給予好評的是,僅僅通過:)
void
DeleteShader
(uint
shader
)
傳遞如果着色器沒有連接到任何程序對象,它是立即刪除。否則,着色器被標記爲刪除,並且在不再附加到任何程序對象時將被刪除。如果某個對象被標記爲刪除,則其布爾狀態位
DELETE_STATUS
設置爲true。
The OpenGL® Graphics System, Version 4.4, Core Profile 2014年3月19日, 81. - §7.1着色器對象。
簡單的答案是:沒關係。您可以在任何時候將它們刪除,然後它們將繼續保持活動狀態,直到它們不再被引用爲止。
着色器生命週期的細節經常被誤解。規範中的關鍵字是:
當着色器對象或程序對象被刪除時,它會被刪除,但其名稱保持有效,直到基礎對象可以被刪除,因爲它不再被使用。着色器對象在附加到任何程序對象時正在使用。程序對象在任何情況下都是當前程序使用。
這在GL 4.4規範的5.1.3部分,並且GL 3.3規範的附錄D.1.2。
因此,與流行的相信相反,如果目前正在使用着色器名稱仍然有效超出glDeleteShader()
調用。這與名稱是如何處理其他對象類型(如紋理或緩衝區)的方式不同,該名稱在刪除調用後立即變爲無效。
這是調用的一個例子序列來說明這些規則:
GLuint progA = glCreateProgram();
GLuint vertA = glCreateShader(GL_VERTEX_SHADER);
glAttachShader(progA, vertA);
glDeleteShader(vertA);
// vertA remains alive, since it's attached to progA.
// Set and compile source for vertA.
GLuint fragA = glCreateShader(GL_FRAGMENT_SHADER);
glAttachShader(progA, fragA);
glDeleteShader(fragA);
// fragA remains alive, since it's attached to progA.
// Set and compile source for fragA.
glLinkProgram(progA);
glUseProgram(progA);
GLuint progB = glCreateProgram();
GLuint vertB = glCreateShader(GL_VERTEX_SHADER);
glAttachShader(progB, vertB);
glDeleteShader(vertB);
// vertB remains alive, since it's attached to progB.
// Set and compile source for vertB.
glAttachShader(progB, fragA);
// Even though we called delete for fragA, we can still use it, since the reference in progA kept it alive.
glLinkProgram(progB);
glUseProgram(progB);
// progA, vertA, fragA, progB, and vertB are all still alive.
glDeleteProgram(progA);
// progA is not referenced anywhere, so it is now deleted.
// Since progA contained the last reference to vertA, vertA is now also deleted.
// progB, vertB and fragA are still valid.
glDeleteProgram(progB);
// progB is the current program, so it remains alive, together with both its attached shaders.
GLint deleteStatus = GL_FALSE;
glGetShaderiv(fragA, GL_DELETE_STATUS, &deleteStatus);
// deleteStatus is GL_TRUE. Note that we could legally use fragA as a name, even though we called glDeleteShader() on it long ago.
glUseProgram(0);
// This releases the last reference to progB, so it is now deleted.
// progB being deleted releases the last reference to vertB and fragA, so both of them are now deleted.
glGetShaderiv(fragA, GL_DELETE_STATUS, &deleteStatus);
// This would now be an error, since fragA is not valid anymore.
事實上,這就是爲什麼3D實驗室可能是唯一真正認爲將着色器對象稱爲「對象」的人首先是一個好主意= P附加和分離是(*或者至少是這樣,直到FBO出現並重新用*)與其他所有對象完全不同,就像刪除時的行爲一樣。它們完全僞裝成GL對象;他們不適合。 –
所以它就像一個智能指針,在那裏你可以釋放引用,但是當沒有對象指向它並且glDeleteShader被調用時,刪除將會發生? – user1767754
@ user1767754或多或少。順便說一句,非常好的答案,'+ 1'。 –
- 1. 是命令「java」的JVM嗎?
- 2. 相當於`du`命令的PHP嗎?
- 3. const INLINE ='inline';與npm相關的命令
- 4. 蝟相關的命令失敗建議
- 5. -mxs命令行開關總是關閉3DSMax嗎?
- 6. 這是命令模式嗎?
- 7. .NET:是「foreach」命令嗎?
- 8. 命令行與命令提示符相同嗎?
- 9. 命令提示符相當於Bash'printf'嗎?
- 10. sql sum命令如果很多表是相關的
- 11. 創建SVG文件和相關命令
- 12. 具有相關性從Linux命令行
- 13. 與楓隔離命令相似的命令是什麼?
- 14. 路徑CMake命令是相等的
- 15. 「git add」的相反命令是什麼?
- 16. Linux中與命令結構有關的命令是什麼
- 17. 是作爲命令可用的figaro嗎?
- 18. 是「ruby腳本/插件」的命令嗎?
- 19. `edit`是合法的bash命令嗎?
- 20. WinDbg的vertarget命令總是準確嗎?
- 21. XOR是MIPS中的僞命令嗎?
- 22. 調用了什麼是{$ {phpinfo()}}? (遠程命令執行相關)
- 23. CFExecute不是ImageMagick的命令
- 24. `buildpacks`不是Heroku的命令
- 25. 命令不是zsh的
- 26. 什麼是MFC中的關機命令?
- 27. GIT commit命令相當於SVN命令
- 28. Pro Django書還是相關的嗎?
- 29. 是與java classloader相關的類鎖嗎?
- 30. 不同的命令提示窗口中不執行相同的命令
這些額外的信息是非常有益的理解。 thx – user1767754