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 和其他“客户端状态命令”不能包含在显示列表中。我想在这种情况下,在glNewListglEndList 之间包含glVertexPointerglNormalPointer 可能没有害处,但我不妨将它们向上移动,以发生在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 函数指针

iOS上的OpenGL ES 1.1:没有剪裁平面?

OpenGL 1.1改变颜色改变以前的颜色?

OpenGL ES 1.1 - alpha 蒙版

glGetString(GL_VERSION) returns “OpenGL ES-CM 1.1” but my phone supports OpenGL 2