【问题标题】:Android - Why i'm getting fatal signal?Android - 为什么我收到致命信号?
【发布时间】:2012-04-17 01:21:31
【问题描述】:

我正在尝试使用 opengl 在屏幕上显示一些点。 这是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);

以及 logcat 的错误:

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

这个错误发生在 gl.glDrawArrays

【问题讨论】:

  • 能否显示错误信息或LogCat?
  • 还需要更多代码。显示缓冲区、点的来源。
  • 致命信号还是异常?尝试在抛出异常时启用中断,看看发生了什么。

标签: android opengl-es


【解决方案1】:

我相信这是问题所在:

gl.glDrawArrays(GL10.GL_POINTS, 0, points.length);

glDrawArrays 获取您要绘制的顶点的数量。你给它的 floats 的数量,太大了 3 倍。因此,opengl 实际上是在尝试从您的 points 数组中读取 12288 vertices = 36,xxx 浮点数,这超出了数组的范围。

【讨论】:

    【解决方案2】:

    问题: 你没有调用 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 命令都可以对您试图让着色器识别的属性数据进行操作。

    【讨论】:

    • 我认为您将 顶点数组顶点缓冲区对象 混淆了。不要求您使用 glBindBuffer 来使用 glDrawArrays。如果未绑定缓冲区,则直接从系统内存中读取数据,而不是从显存中的缓冲区中读取数据。
    • @Tim:嗯,也许你是对的。无论如何,我都会在这里留下我的答案,以防万一它可以帮助其他使用 VBO 的人,并且想知道他们为什么会出现同样的错误……只需阅读您的个人资料。你在 NVIDIA 工作。你当然是对的。仍然会在这里留下答案,因为当我在使用 VBO 时忘记做我提到的事情时遇到了这个问题。无法击败自己在显卡上工作的人的答案。 :D 干杯。 +1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    相关资源
    最近更新 更多