我一直注意到程序中存在少量内存泄漏,我终于能够找到问题所在。
我正在做的是通过调用此函数将5个矩形绘制到屏幕上:
bool OpenGlEntity::fillRect(SDL_Rect rect, float R, float G, float B, float A){
glPushMatrix();
glDisable(GL_TEXTURE_2D);
GLfloat vertices_position[] = {
(GLfloat)rect.x, (GLfloat)rect.y,
(GLfloat)(rect.x+rect.w), (GLfloat)rect.y,
(GLfloat)(rect.x+rect.w), (GLfloat)(rect.y+rect.h),
(GLfloat)rect.x, (GLfloat)(rect.y+rect.h),
};
glTranslatef(0, 0, 0);
//scale
glScalef(1,1,1);
//set color
glColor4f(R, G, B, A);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices_position);
glLockArraysEXT(0, 4);
glDrawArrays(GL_QUADS, 0, 4);
glUnlockArraysEXT();
glDisableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_2D);
//reset color
glColor4f(1.f, 1.f, 1.f, 1.f);
glPopMatrix();
return true;}
如果我从不运行“glDisable(GL_TEXTURE_2D);” (或“glEnable(GL_TEXTURE_2D);”)泄漏不会发生。这是为什么?
对我而言,它没有多少意义,但是我再次对OpenGL渲染没有经验。
答案 0 :(得分:0)
有许多原因可以让您感知启用或禁用某个特定状态会导致内存“泄漏”。例如,如果在纹理上启用三线性过滤并且纹理没有mipmap数据,则驱动程序通常会为mipmap链/金字塔分配内存(无论它是否生成实际的mipmap级别)。这会导致内存消耗增长约33%,原因很简单,因为您更改了纹理过滤器状态。
顺便说一下,绘制调用并不是内存增加的真正来源。绘制调用通常是驱动程序提交排队命令的点。这就是为什么你不能计算对glEnable(...)或glDisable(...)的调用持续时间,并测量改变该状态的开销。智能驱动程序将在最后一次绘制调用和当前之间运行所有状态更改请求,这是大多数状态设置确实发生的时间。因此,在您的情况下,驱动程序可能会推迟一些纹理设置操作,直到第一次绑定和启用纹理单元和/或对象为止。因此,当您发出绘制调用时,驱动程序会在执行的任务清单期间为纹理分配内存。
对应用程序进行概要分析是很诱人的,看看glDraw(...)似乎是你的瓶颈,并假设你是顶点绑定的,但在很多情况下这不可能是事实:)这只是您需要更多专用工具和API来有效调试,跟踪内存资源分配以及配置使用GPU的应用程序的众多原因之一。
在任何情况下,您遇到的可能性都是正常行为,驱动程序必须在多个位置(CPU,GPU等)分配内存以处理“设备丢失”等事件。如果“泄漏”是一次性发生,您可以忽略它并将其记录到驱动程序内存管理中。