2016-01-18 27 views
2

在編譯頂點着色器或片段着色器時,是否應該在未能編譯的着色器上調用glDeleteShader()函數,或只適用於成功編譯的着色器?OpenGL3:在着色器編譯失敗後清理

例如,使用着色器

const GLchar* vertexSource = 
    "#version 150 core\n" 
    "in vec2 position;" // Vertices specified in 2 dimensions: (X, Y) 
    "void main()" 
    "{" 
    " gl_Position = vec4(position, 0.0, 1.0)" // Removed semicolon here 
    "}"; 

這是由於破裂而缺少分號,會同:

GLuint vertexShader; 
vertexShader = glCreateShader(GL_VERTEX_SHADER); 

glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); 
glCompileShader(vertexShader); 

GLint success; 

glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); 

if (!success) { 
    GLchar infoLog[512]; 
    glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); 
    std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; 
} 

將觸發if-子句由於syntax-錯誤:error: syntax error, unexpected '}', expecting ',' or ';'

我曾嘗試在if子句中添加glDeleteShader(vertexShader);以及將其遺漏,但無法區分程序在退出時的行爲方式。

着色器應該被刪除嗎?

回答

2

無論是否成功編譯,着色器對象都存在。所以是的,即使編譯失敗,也應該刪除它。

着色器對象實際上存儲着您在glShaderSource中提供的着色器字符串(您可以使用glGetShaderSource檢索它們)。所以雖然它們不是GPU對象,但它們並不是完全輕量級的。

but cannot discern any difference in how the program behaves as it exits.

你也不期望。與分配char*字符串並且在程序退出時忘記刪除它並沒有什麼不同。你不會注意到你一次泄漏的小內存。

1

從OpenGL的單證:

glDeleteShader frees the memory and invalidates the name associated with the shader object specified by shader. This command effectively undoes the effects of a call to glCreateShader().

這意味着,如果編譯成功與否,內存將保持分配。所以,是的,你需要調用glDeleteShader