【问题标题】:OpenGL ES 2.0 Vertex Bug Garbage Collector (Android)OpenGL ES 2.0 顶点错误垃圾收集器 (Android)
【发布时间】:2016-06-27 09:03:12
【问题描述】:

我正在使用 android 上的 opengl-es 2.0 绘制一个简单的三角形(在 nexus4 上测试)。

在连续绘制模式下,我使用旋转矩阵旋转这个三角形,并在顶点着色器中设置 uMVPMatrix。

问题

我是打开 gl 的新手,但这很基本并且效果很好,但是大约 30 秒后,垃圾收集器开始工作:

05-05 19:12:23.359  26333-26357/com.x.app V/Renderer﹕ Surface created
05-05 19:12:23.369  26333-26357/com.x.app V/Renderer﹕ Changed surface width:1196 height: 768
05-05 19:12:59.307  26333-26357/com.x.app D/dalvikvm﹕ GC_FOR_ALLOC freed 436K, 5% free 9121K/9588K, paused 64ms, total 65ms
05-05 19:13:48.910  26333-26357/com.x.app D/dalvikvm﹕ GC_FOR_ALLOC freed 522K, 6% free 9105K/9664K, paused 31ms, total 31ms
05-05 19:14:39.144  26333-26357/com.x.app D/dalvikvm﹕ GC_FOR_ALLOC freed 512K, 6% free 9104K/9664K, paused 13ms, total 13ms

在第二个 GC Round 之后,屏幕上会出现另一个 Rectangle,有时是 Line。 Another image here

一两次垃圾收集器运行后,它又消失了,这种情况一遍又一遍地发生。

我猜在着色器代码和 java 之间有一些绑定,我做错了。

我的代码

我的三角形绘制方法:

 public void draw(float[] mMVPMatrix) {
    GLES20.glUseProgram(mProgram);
    int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false,
            vertexStride, vertexBuffer);
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}

顶点缓冲区(三角形构造函数):

    ByteBuffer bb = ByteBuffer.allocateDirect(
            triangleCoords.length * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(triangleCoords);
    vertexBuffer.position(0);
    vertexCount=triangleCoords.length;

【问题讨论】:

  • 您的着色器实际上与这个问题完全无关。实际发生的事情很可能与您的顶点指针设置有关。特别是,如果您创建一个指向不是 "direct" 的缓冲区的指针,那么 JVM 将使 OpenGL 的生活变得悲惨。你在使用 VBO 吗?
  • 谢谢,是的。我编辑了我的帖子。顶点缓冲区对我来说看起来不错(也许我错了),但我想知道我是否应该/可以为 mvp 矩阵使用缓冲区。

标签: android opengl-es garbage-collection opengl-es-2.0


【解决方案1】:

您应该使用 DDMS 'Start Tracking''Get Allocations' 按钮来跟踪内存分配。它会显示你所有的分配。更多信息在这里:http://developer.android.com/tools/debugging/ddms.html#alloc

查看您的代码,我强烈建议您在编译着色器后立即调用GLES20.glGetUniformLocation 一次,并将这些值存储在int 变量中。通过字符串标识符查找制服/属性相当耗时,而且我的猜测是它也会分配一些内存(不多,但您在 每个 帧中都这样做)。不要在每次绘制调用时都这样做。

除此之外,这个问题与 OpenGL ES 无关,它是一个常见的垃圾收集问题,您可以在 DDMS 中轻松跟踪。

【讨论】:

  • 没错。在绘制每一帧之前分配缓冲区/纹理也会产生这种奇怪的OpenGL绘制行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多