OpenGL 1.1:调用 glNormalPointer() 后可以释放内存吗?
Posted
技术标签:
【中文标题】OpenGL 1.1:调用 glNormalPointer() 后可以释放内存吗?【英文标题】:OpenGL 1.1: Can memory be freed after calling glNormalPointer()? 【发布时间】:2019-11-08 00:29:59 【问题描述】:我有一些使用 OpenGL 1.1 的旧代码神秘地出现了段错误。我可能会出错的一个地方是我在将数组提供给glNormalPointer
之后free()
。这是允许的,还是 OpenGL 需要该指针处的内存才能保留?我一直假设数据被复制了。
double vertices[] = ... ;
double *normals = (double *)malloc(sizeof(vertices));
CalcNormals(vertices, normals, num_vertices); // Calculate the normal vectors.
GLuint my_display_list = glGenLists(1);
glNewList(my_display_list, GL_COMPILE);
glVertexPointer(3, GL_DOUBLE, 0, vertices);
glNormalPointer(GL_DOUBLE, 0, normals);
glDrawArrays(GL_TRIANGLES, 0, num_vertices);
glEndList();
free(normals); // Is this permitted?
// ...
glCallList(winglist);
编辑 1:我注意到一些参考资料说 glNormalPointer 和其他“客户端状态命令”不能包含在显示列表中。我想在这种情况下,在glNewList
和glEndList
之间包含glVertexPointer
和glNormalPointer
可能没有害处,但我不妨将它们向上移动,以发生在glNewList
之前。真正记录在显示列表中的是对glDrawArrays
的调用,对吧?
编辑 2:我尝试调用 memset(normals, 0, sizeof(vertices))
在释放法线缓冲区之前强制清除它,以使释放后使用情况更加明显。因为场景仍然可以正确绘制,所以我得出结论,在调用 glDrawArrays
之后,我分配的法线缓冲区没有被使用。
【问题讨论】:
你有没有尝试过调试器来查看错误访问是什么? @derhass - 问题是它在我的机器上运行良好,但我有报告说它对其他人有段错误。 【参考方案1】:我注意到一些参考资料说 glNormalPointer 和其他“客户端状态命令”不能包含在显示列表中。
不,它表示它们不包含在显示列表中。这是真的;他们不是。
但它们的效果可以。
gl*Pointer
命令retain the pointer well after their the command executes。也就是说,指针尚未使用。只有当您使用该指针作为客户端状态调用渲染命令时才会读取它。
glDraw*
调用客户端顶点数组的行为是根据在 glBegin/End
对中对 glArrayElement
的调用序列定义的,它本身是根据对 @987654326 的一系列调用定义的@,使用从顶点数组中读取的值。显示列表将那些glVertex/etc
调用记录到显示列表本身中。因此,在记录到显示列表时,当您使用客户端顶点数组进行渲染时,您会将数组的内容记录到显示列表中。
只有在不再尝试读取客户端内存时,才能释放客户端内存。
【讨论】:
以上是关于OpenGL 1.1:调用 glNormalPointer() 后可以释放内存吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 CADisplayLink 的 iOS OpenGL ES 1.1 生涩动画(重启修复了一段时间)
Windows 上的 OpenGL 1.0 和 1.1 函数指针
glGetString(GL_VERSION) returns “OpenGL ES-CM 1.1” but my phone supports OpenGL 2