0

我注意到我的程序中有一个小的内存泄漏,我终于能够找到问题所在。

我正在做的是通过调用此函数在屏幕上绘制 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 渲染方面没有那么有经验。

4

1 回答 1

0

有很多原因可以让您感觉到启用或禁用特定状态会导致内存“泄漏”。例如,如果您在纹理上启用三线性过滤并且纹理没有 mipmap 数据,则驱动程序通常会最终为 mipmap 链/金字塔分配内存(无论它是否生成实际的 mipmap 级别)。仅仅因为您更改了纹理过滤器状态,这将导致约 33% 的内存消耗增长。

顺便说一句,绘图调用并不是真正增加内存的来源。绘图调用通常是驱动程序提交排队命令的点。这就是为什么您无法确定调用 glEnable (...) 或 glDisable (...) 的持续时间并衡量更改该状态的开销的原因。智能驱动程序将在最后一次绘制调用和当前调用之间运行所有状态更改请求,这是大多数状态设置真正发生的时候。因此,在您的情况下,驱动程序可能会推迟一些纹理设置操作,直到第一次绑定和启用纹理单元和/或对象。结果,驱动程序在您发出绘图调用时执行的任务清单中最终为纹理分配内存。

分析应用程序很诱人,看到 glDraw (...) 似乎是您的瓶颈并假设您是顶点绑定的,但在许多情况下这与事实相去甚远 :) 这只是其中之一您需要更多专用工具和 API 来有效调试、跟踪内存资源分配和分析使用 GPU 的应用程序的原因。

在任何情况下,您遇到的可能都是正常行为,驱动程序必须在多个位置(CPU、GPU 等)分配内存来处理诸如“设备丢失”之类的事件。如果“泄漏”是一次性的,您可以忽略它并将其归咎于驱动程序内存管理。

于 2013-07-29T18:01:29.920 回答