我發現很多時候,OpenGL會通過不繪製任何東西來顯示它失敗。我試圖找到調試OpenGL程序的方法,通過檢查轉換矩陣堆棧等。什麼是調試OpenGL的最佳方式?如果代碼的外觀和感覺像頂點在正確的位置,你怎麼確定它們是?什麼是調試OpenGL的最佳方式?
回答
沒有直接的答案。這一切都取決於你想要了解的內容。由於OpenGL是一個狀態機,有時它不會做你期望的,因爲沒有設置所需的狀態或類似的東西。通常,使用glTrace/glIntercept(查看OpenGL調用跟蹤),gDebugger(用於可視化紋理,着色器,OGL狀態等)和紙/鉛筆:)等工具。有時候,這有助於瞭解你如何安裝攝像機以及它正在查看的內容,正在剪輯的內容等。我個人比以前的兩種方法更依賴於最後一個。但是當我可以爭辯深度錯誤的時候,它有助於觀察痕跡。 gDebugger也是的唯一的工具,可以有效地用於分析和優化您的OpenGL應用程序。
除了這個工具之外,大部分時間都是人們弄錯了,而且不能用任何工具理解的數學。在OpenGL.org新聞組上發佈代碼特定評論,你永遠不會失望。
GLIntercept是你最好的選擇。從他們的網頁:
- 將所有OpenGL函數調用保存爲文本或XML格式,並且可以選擇記錄單個幀。
- 免費攝像頭。圍繞發送到顯卡的幾何圖形飛行,並啓用/禁用線框/背面剔除/視錐體渲染
- 保存並跟蹤顯示列表。 保存OpenGL幀緩衝區(顏色/深度/模板)前後渲染調用。還可以保存前後圖像的「差異」。
還有免費的glslDevil:http://www.vis.uni-stuttgart.de/glsldevil/
它允許您調試GLSL着色器廣泛。它還顯示失敗的OpenGL調用。
但是它缺少檢查紋理和屏幕外緩衝區的功能。
對於Mac上的那些人,OpenGL調試器中的buit也很棒。它允許您檢查緩衝區,狀態並幫助查找性能問題。
我發現,您可以檢查每一行代碼的犯罪嫌疑人將是錯誤的之後,使用glGetError
,但經過這樣做,代碼看起來不是很乾淨,但它的工作原理。
gDebugger是一個優秀的免費工具,但不再支持。然而,AMD已經拿起了它的發展,而這個調試器現在被稱爲CodeXL。它既可以作爲獨立應用程序使用,也可以作爲Visual Studio插件使用 - 既可用於本機C++應用程序,也可用於使用OpenGL綁定的Java/Python應用程序,這兩種應用程序均可用於NVidia和AMD GPU。這是一個工具的地獄。
Apitrace是來自Valve的一些人的一個相對較新的工具,但它工作的很棒!試一試:https://github.com/apitrace/apitrace
Nsight如果你有一個NVidia卡是很好的調試工具。
什麼是調試OpenGL的最好方法是什麼?
沒有考慮額外和外部工具(其他答案已經這樣做)。
話,一般的辦法是廣泛地調用glGetError()
。然而更好的選擇是使用Debug Output(KHR_debug,ARB_debug_output)。這爲您提供了爲不同嚴重級別消息設置回調的功能。
爲了使用調試輸出,上下文必須使用WGL/GLX_DEBUG_CONTEXT_BIT
標誌創建。 With GLFW this can be set with the GLFW_OPENGL_DEBUG_CONTEXT
window hint。
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
請注意,如果上下文不是調試上下文,則不能保證接收所有甚至任何消息。
無論你是否有一個調試上下文與否可以通過檢查GL_CONTEXT_FLAGS
進行檢測:
GLint flags;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
// It's a debug context
這樣,你會繼續前進,指定一個回調:
void debugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
// Print, log, whatever based on the enums and message
}
的枚舉can be seen on here每個可能值。特別要記住要檢查嚴重性,因爲有些消息可能只是通知而不是錯誤。
您現在可以提前完成註冊回調。
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(debugMessage, NULL);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
你甚至可以使用glDebugMessageInsert()
注入自己的消息。
glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0,
GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Vary dangerous error");
當涉及到着色器和程序,你總是希望被檢查GL_COMPILE_STATUS
,GL_LINK_STATUS
和GL_VALIDATE_STATUS
。如果他們中的任何一個反映出有問題,那麼另外總是檢查glGetShaderInfoLog()
/glGetProgramInfoLog()
。
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (!linkStatus)
{
GLchar *infoLog = new GLchar[infoLogLength + 1];
glGetProgramInfoLog(program, infoLogLength * sizeof(GLchar), NULL, infoLog);
...
delete[] infoLog;
}
通過glGetProgramInfoLog()
返回的字符串將空終止。
你也可以去多一點極端,利用在調試版本的幾個調試宏。因此,使用glIs*()
函數來檢查預期類型是否也是實際類型。
assert(glIsProgram(program) == GL_TRUE);
glUseProgram(program);
如果調試輸出是不可用,你只是想用glGetError()
,那麼你當然可以這樣做。
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR)
printf("OpenGL Error: %u\n", err);
因爲一個數字錯誤代碼是不是有幫助的,我們可以把它多一點人類可讀通過映射的數字錯誤代碼的消息。
const char* glGetErrorString(GLenum error)
{
switch (error)
{
case GL_NO_ERROR: return "No Error";
case GL_INVALID_ENUM: return "Invalid Enum";
case GL_INVALID_VALUE: return "Invalid Value";
case GL_INVALID_OPERATION: return "Invalid Operation";
case GL_INVALID_FRAMEBUFFER_OPERATION: return "Invalid Framebuffer Operation";
case GL_OUT_OF_MEMORY: return "Out of Memory";
case GL_STACK_UNDERFLOW: return "Stack Underflow";
case GL_STACK_OVERFLOW: return "Stack Overflow";
case GL_CONTEXT_LOST: return "Context Lost";
default: return "Unknown Error";
}
}
然後檢查它是這樣的:
printf("OpenGL Error: [%u] %s\n", err, glGetErrorString(err));
那還不是很有益的或更好的直觀的說,好像你已經撒了幾glGetError()
在這裏和那裏。然後找到哪一個記錄錯誤可能會很麻煩。
再次宏來救援。
void _glCheckError(const char *filename, int line)
{
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR)
printf("OpenGL Error: %s (%d) [%u] %s\n", filename, line, err, glGetErrorString(err));
}
現在只需像這樣定義一個宏:
#define glCheckError() _glCheckError(__FILE__, __LINE__)
,瞧,現在你可以選擇你想要的一切後打電話glCheckError()
,並在錯誤的情況下,它會告訴你確切的文件和行是檢測到。
動態更新窗口標題對我來說很方便。
示例(使用GLFW,C++ 11):
glfwSetWindowTitle(window, ("Now Time is " + to_string(glfwGetTime())).c_str());
- 1. 調試AJAX到PHP調用的最佳方式是什麼?
- 2. python中交互式調試的最佳方式是什麼?
- 3. 什麼是調試asp頁面的最佳方式?
- 4. 調試時可視化DataTable的最佳方式是什麼?
- 5. 調試SOAP交互的最佳方式是什麼?
- 6. 什麼是調試Adobe Flex CSS的最佳方式?
- 7. 在Visual Studio中調試程序的最佳方式是什麼?
- 8. 在IBM Connections上調試JavaScript的最佳方式是什麼?
- 9. 繪製分層OpenGL ES內容的最佳方式是什麼?
- 10. 什麼是最佳調試提示?
- 11. 鍵入()的最佳方式是什麼?
- 12. 什麼是開源的最佳方式?
- 13. 「投票」的最佳方式是什麼?
- 14. 調試崩潰的explorer.exe的最佳方法是什麼?
- 15. Django DatabaseError - 調試的最佳方法是什麼?
- 16. 調試Shoes應用程序的最佳方法是什麼?
- 17. 調試Bootstrap.groovy的最佳方法是什麼?
- 18. 調試性能問題的最佳方法是什麼?
- 19. 測試iPod Touch的iPhone遊戲的最佳方式是什麼?
- 20. 測試rails應用程序的最佳方式是什麼?
- 21. 什麼是測試GWT代碼的最佳方式
- 22. 什麼是測試RedirectToAction的最佳方式?
- 23. 測試XML響應的最佳方式是什麼?
- 24. MVCContrib - 測試XMLResult的最佳方式是什麼?
- 25. 測試Rails REST XML API的最佳方式是什麼?
- 26. 設置和測試Lambda API的最佳方式是什麼?
- 27. 什麼是測試Web服務網關的最佳方式?
- 28. 什麼是實施在線測試的最佳方式?
- 29. 測試Atom服務器的最佳方式是什麼?
- 30. 什麼是測試郵件列表軟件的最佳方式?
有學術許可也是如此,如果你的質量 – Ketan 2009-02-05 22:12:17
由於這個問題仍然流行的了,也許國防部可以對其進行編輯和正確的,現在是免費的? – NoxMortem 2016-03-13 21:31:33