安卓 - 为什么会出现致命信号?

3

我将尝试使用OpenGL ES在屏幕上显示一些点。

以下是ondraw的代码:

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColor4f(0, 255, 0, 0);     
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, buffer);
gl.glDrawArrays(GL10.GL_POINTS, 0, points.length);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

有人能告诉我我做错了什么吗???

编辑:生成缓冲区和点的代码

    points = new float[12288];
    int pos = 0;
    for (float y = 0; y < 64; y++) {
        for (float x = 0; x < 64; x++) {
            points[pos++] = x/100;
            points[pos++] = y/100;
            points[pos++] = 0;
        }
    }

    ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(points.length * 4);
    vertexByteBuffer.order(ByteOrder.nativeOrder());     
    // allocates the memory from the byte buffer
    buffer = vertexByteBuffer.asFloatBuffer();   
    // fill the vertexBuffer with the vertices
    buffer.put(points);  
    // set the cursor position to the beginning of the buffer
    buffer.position(0);

日志中的错误信息:

04-17 06:38:11.296: A/libc(24276): 致命信号 11 (SIGSEGV) 于 0x41719000 处(代码=2)

该错误发生在 gl.glDrawArrays 函数。


1
你能展示错误信息或LogCat吗? - chandsie
需要更多的代码。同时展示缓冲区和点来自哪里。 - Tim
致命信号或异常?尝试在抛出异常时启用中断,看看发生了什么。 - Stefan Hanke
2个回答

2
我认为这是问题所在:
glDrawArrays需要指定要绘制的顶点数。你给它的是floats的数量,这个数量实际上是3倍太大了。因此,OpenGL实际上试图从你的points数组中读取12288个顶点= 36,xxx个floats,这远远超出了你的数组边界。

0
问题:您尚未调用glBindBuffer,但随后调用了glDrawArrays;这将导致段错误。

当我尝试使用IBO缓冲区而没有使用glBindBuffer命令绑定缓冲区时,我遇到了同样的问题。例如,我的一个绘制函数如下所示:

GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, common.vbo);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, common.ibo);

GLES20.glVertexAttribPointer(handleManager.switchPosition, 2, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(handleManager.switchPosition);

GLES20.glDrawElements(GLES20.GL_TRIANGLES, common.iboPointCount, GLES20.GL_UNSIGNED_BYTE, 0);

GLES20.glDisableVertexAttribArray(handleManager.switchPosition);

GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

所有的glBindBuffer命令都可以让你对属性数据进行操作,以便让着色器识别。

1
我认为你把“顶点数组”和“顶点缓冲对象”混淆了。使用glDrawArrays并不一定需要使用glBindBuffer。如果没有绑定缓冲区,则数据直接从系统内存中读取,而不是从视频内存中的缓冲区读取。 - Tim
@Tim:嗯,也许你是对的。我还是要把我的答案留在这里,以防有其他使用VBO并想知道为什么会出现相同错误的人需要帮助...刚刚看了一下你的个人资料,你在NVIDIA工作。你肯定是对的。不过我还是要把答案留在这里,因为我在使用VBO时曾经遇到过这个问题,当时忘记做我提到的事情了。毕竟从那些制作显卡的人那里得到答案是无可比拟的。:D 干杯。+1 - Robert Massaioli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接