glDeleteShader语言 - 是顺序无关
glDeleteShader - is the order irrelevant?
在OpenGL中,glAttachShader
的顺序无关紧要,glDeleteShader
的顺序是否相同?如果有一些动态内存分配正在进行,我会说是的,但也许这在opengl上下文中处理得不同。
简单的回答是:没关系。在附加到程序后,您可以随时删除它们,并且它们将继续有效,直到不再被引用。
着色器寿命的细节经常被误解。规范中的关键措辞是:
当一个着色器对象或程序对象被删除时,它被标记为删除,但它的名称仍然有效,直到底层对象可以被删除,因为它不再使用。当着色器对象被附加到任何程序对象时,它正在使用。当程序对象在任何上下文中是当前程序时,它正在被使用。
这在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.
不,你删除着色器的顺序是大多数不重要。
我说大多数情况下,因为它不会有太大的意义,删除你的着色器之前,你附加到并链接你的GLSL程序。然而,一旦程序被链接,你可以对着色器做任何你想做的事情。
OpenGL中的对象删除由驱动程序处理,并不一定立即发生。它必须以这种方式工作,因为OpenGL可能会将仍然引用您试图删除的对象的命令排队。如果它立即删除它们,那么已经发出但尚未完成的命令将具有未定义的结果。相反,GL删除对象内存在之后的某个时间你调用glDelete* (...)
,当没有其他保存对它的引用。
当您调用glDelete* (..)
时,GL将立即做的唯一事情是释放对象名称以供glGen* (...)
命令重用(并将其从当前上下文中解绑定)。内存回收将在将来的某个时间点进行。
是-着色器可以按你喜欢的任何顺序删除。Create
/Delete
遵循与malloc
/free
相同的语义,用于原始内存块
不要投票,只是路过:)
void
DeleteShader
(uint
shader
)
如果shader没有附加到任何程序对象,它将被立即删除。否则,着色器被标记为删除,当它不再附加到任何程序对象时将被删除。如果一个对象被标记为删除,它的布尔状态位
DELETE_STATUS
被设置为true。
The OpenGL®Graphics System, Version 4.4, Core Profile, 2014年3月19日,第81页。-§7.1 Shader Objects.
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 数到第n个楼梯的路(顺序无关紧要)
- 优先顺序:智能指针和类析构函数
- 在循环中按顺序遍历成员变量
- 独立读取-修改-写入顺序
- QML按钮点击功能执行顺序
- 不同语言中相同代码的不同行为
- C++中数据类型修饰符的顺序
- 当比特(而不是字节)的顺序至关重要时的持久性
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 通过选项卡的文本设置QTabWidget顺序
- 为什么在未由语言本身定义的结构字节中的位字段顺序
- 如何在 Windows 8 中更改语言列表顺序
- C语言中等优先级操作数的计算顺序
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的
- glDeleteShader语言 - 是顺序无关
- 语言律师- c++:隐式转换顺序