OpenGL3:着色器编译失败后进行清理

时间:2016-01-18 17:16:26

标签: c++ opengl opengl-3

在编译顶点或片段着色器时,是否应该调用未能编译的着色器上的glDeleteShader()函数,或者它是否仅适用于成功编译的着色器?

例如,使用着色器

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子句:error: syntax error, unexpected '}', expecting ',' or ';'

我已尝试在if子句中添加glDeleteShader(vertexShader);并将其删除,但无法识别程序退出时的行为方式。

是否应删除着色器?

2 个答案:

答案 0 :(得分:2)

无论是否成功编译,都存在着色器对象。所以是的,你应该删除它,即使它编译失败。

着色器对象实际上具有您在glShaderSource中提供的着色器字符串的存储空间(您可以使用glGetShaderSource检索它们)。因此,虽然它们不是GPU对象,但它们并不完全是轻量级的。

  

但无法辨别程序在退出时的行为方式有何不同。

你也不期望。它与分配char*字符串然后忘记在程序退出时删除它没有什么不同。你不会注意到你曾经泄露过的小记忆。

答案 1 :(得分:1)

来自OpenGL文档:

  

glDeleteShader释放内存并使与着色器指定的着色器对象关联的名称无效。此命令有效地撤消了对glCreateShader()的调用的影响。

这意味着如果编译成功与否,内存将保持分配状态。所以,是的,你需要调用glDeleteShader