【问题标题】:OpenGL3: Clean-up after failed shader compilationOpenGL3:着色器编译失败后的清理
【发布时间】:2016-01-18 17:16:25
【问题描述】:

在编译顶点着色器或片段着色器时,是否应该在编译失败的着色器上调用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); 并将其排除在外,但无法辨别程序在退出时的行为方式有何不同。

是否应该删除着色器?

【问题讨论】:

    标签: c++ opengl opengl-3


    【解决方案1】:

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

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

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

    您也不希望如此。这与分配char* 字符串然后在程序退出时忘记删除它没有什么不同。你不会注意到你泄漏的小内存。

    【讨论】:

      【解决方案2】:

      来自 OpenGL 文档:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多