在编译顶点或片段着色器时,是否应该调用未能编译的着色器上的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);
并将其删除,但无法识别程序退出时的行为方式。
是否应删除着色器?
答案 0 :(得分:2)
无论是否成功编译,都存在着色器对象。所以是的,你应该删除它,即使它编译失败。
着色器对象实际上具有您在glShaderSource
中提供的着色器字符串的存储空间(您可以使用glGetShaderSource
检索它们)。因此,虽然它们不是GPU对象,但它们并不完全是轻量级的。
但无法辨别程序在退出时的行为方式有何不同。
你也不期望。它与分配char*
字符串然后忘记在程序退出时删除它没有什么不同。你不会注意到你曾经泄露过的小记忆。
答案 1 :(得分:1)
来自OpenGL文档:
glDeleteShader释放内存并使与着色器指定的着色器对象关联的名称无效。此命令有效地撤消了对glCreateShader()的调用的影响。
这意味着如果编译成功与否,内存将保持分配状态。所以,是的,你需要调用glDeleteShader