gpt4 book ai didi

c++ - glDeleteShader - 顺序无关紧要吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:12:56 25 4
gpt4 key购买 nike

在 OpenGL 中,glAttachShader 的顺序无关紧要,这与 glDeleteShader 的顺序相同吗?如果正在进行一些动态内存分配,我会说是的,但也许这在 opengl 上下文中的处理方式不同。

最佳答案

简单的回答是:没关系。在将它们附加到程序后,您可以随时删除它们,它们将继续保持事件状态,直到不再被引用。

着色器生命周期的细节经常被误解。规范中的关键措辞是:

When a shader object or program object is deleted, it is flagged for deletion, but its name remains valid until the underlying object can be deleted because it is no longer in use. A shader object is in use while it is attached to any program object. A program object is in use while it is the current program in any context.

这在 GL 4.4 规范的第 5.1.3 节和 GL 3.3 规范的附录 D.1.2 中。

因此与普遍的看法相反,着色器名称在 glDeleteShader() 调用之后仍然有效,如果它当前正在使用中。这与其他对象类型(如纹理或缓冲区)的名称处理方式不同,在这些类型中,名称在 delete 调用后立即失效。

这是说明这些规则的示例调用序列:

GLuint progA = glCreateProgram();
GLuint vertA = glCreateShader(GL_VERTEX_SHADER);
glAttachShader(progA, vertA);
glDeleteShader(vertA);
// vertA remains alive, since it's attached to progA.
// Set and compile source for vertA.
GLuint fragA = glCreateShader(GL_FRAGMENT_SHADER);
glAttachShader(progA, fragA);
glDeleteShader(fragA);
// fragA remains alive, since it's attached to progA.
// Set and compile source for fragA.
glLinkProgram(progA);
glUseProgram(progA);

GLuint progB = glCreateProgram();
GLuint vertB = glCreateShader(GL_VERTEX_SHADER);
glAttachShader(progB, vertB);
glDeleteShader(vertB);
// vertB remains alive, since it's attached to progB.
// Set and compile source for vertB.
glAttachShader(progB, fragA);
// Even though we called delete for fragA, we can still use it, since the reference in progA kept it alive.
glLinkProgram(progB);
glUseProgram(progB);

// progA, vertA, fragA, progB, and vertB are all still alive.
glDeleteProgram(progA);
// progA is not referenced anywhere, so it is now deleted.
// Since progA contained the last reference to vertA, vertA is now also deleted.
// progB, vertB and fragA are still valid.
glDeleteProgram(progB);
// progB is the current program, so it remains alive, together with both its attached shaders.

GLint deleteStatus = GL_FALSE;
glGetShaderiv(fragA, GL_DELETE_STATUS, &deleteStatus);
// deleteStatus is GL_TRUE. Note that we could legally use fragA as a name, even though we called glDeleteShader() on it long ago.

glUseProgram(0);
// This releases the last reference to progB, so it is now deleted.
// progB being deleted releases the last reference to vertB and fragA, so both of them are now deleted.

glGetShaderiv(fragA, GL_DELETE_STATUS, &deleteStatus);
// This would now be an error, since fragA is not valid anymore.

关于c++ - glDeleteShader - 顺序无关紧要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24172962/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com