glDrawElements()崩溃棒棒糖,但在KitKat上没问题

时间:2015-05-27 02:24:06

标签: java android opengl-es bytebuffer

我正在尝试学习OpenGL ES 1.0 for Android。我的应用程序运行正常,直到我今天早上将设备升级到Android 5.0.1,Lollipop。我最初尝试调试此问题很快就发现我的应用程序仍在运行KitKat的模拟器上运行,但在我的设备和模拟器上的Lollipop上都崩溃了。

我的应用程序使用OpenGL绘制一个简单的立方体,每边都有不同的纹理。我把它弄到了glDrawElements()行崩溃的地方。

package com.briansworld.gravitycubestep7;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

// draw a cube
// store the cube's position within the multicube
// bind the textures here
class Cube
{
    private FloatBuffer mVertexBuffer;
    private FloatBuffer myTexBuffer;
    private ByteBuffer myIndexBuffer;
    public int x, y, z;  // used to keep track of which cube is which, not cube position

    // constructor
    public Cube(int x, int y, int z) // need to add texture ID's
    {
        this.x = x;
        this.y = y;
        this.z = z;

        float vertices[] =
                {
                        -1.0f, -1.0f,  1.0f,  // front
                         1.0f, -1.0f,  1.0f,
                        -1.0f,  1.0f,  1.0f,
                         1.0f,  1.0f,  1.0f,

                         1.0f, -1.0f,  1.0f,  // right
                         1.0f, -1.0f, -1.0f,
                         1.0f,  1.0f,  1.0f,
                         1.0f,  1.0f, -1.0f,

                         1.0f, -1.0f, -1.0f,  // rear
                        -1.0f, -1.0f, -1.0f,
                         1.0f,  1.0f, -1.0f,
                        -1.0f,  1.0f, -1.0f,

                        -1.0f, -1.0f, -1.0f,  // left
                        -1.0f, -1.0f,  1.0f,
                        -1.0f,  1.0f, -1.0f,
                        -1.0f,  1.0f,  1.0f,

                        -1.0f, -1.0f, -1.0f,  // bottom
                         1.0f, -1.0f, -1.0f,
                        -1.0f, -1.0f,  1.0f,
                         1.0f, -1.0f,  1.0f,

                        -1.0f,  1.0f, -1.0f,  // top
                         1.0f,  1.0f, -1.0f,
                        -1.0f,  1.0f,  1.0f,
                         1.0f,  1.0f,  1.0f
                };

        float texBuffer[] =
                {
                        0.0f, 1.0f,
                        1.0f, 1.0f,
                        0.0f, 0.0f,
                        1.0f, 0.0f,

                        0.0f, 1.0f,
                        1.0f, 1.0f,
                        0.0f, 0.0f,
                        1.0f, 0.0f,

                        0.0f, 1.0f,
                        1.0f, 1.0f,
                        0.0f, 0.0f,
                        1.0f, 0.0f,

                        0.0f, 1.0f,
                        1.0f, 1.0f,
                        0.0f, 0.0f,
                        1.0f, 0.0f,

                        0.0f, 1.0f,
                        1.0f, 1.0f,
                        0.0f, 0.0f,
                        1.0f, 0.0f,

                        0.0f, 1.0f,
                        1.0f, 1.0f,
                        0.0f, 0.0f,
                        1.0f, 0.0f
                };

        byte indexBuffer[] =
                {
                         0,  1,  3,    0,  3,  2,
                         4,  5,  7,    4,  7,  6,
                         8,  9, 11,    8, 11, 10,
                        12, 13, 15,   12, 15, 14,
                        16, 17, 19,   16, 19, 18,
                        20, 21, 23,   20, 23, 22
                };

        ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        mVertexBuffer = byteBuf.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);

        byteBuf = ByteBuffer.allocateDirect(texBuffer.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        myTexBuffer = byteBuf.asFloatBuffer();
        myTexBuffer.put(texBuffer);
        myTexBuffer.position(0);

        myIndexBuffer = ByteBuffer.allocate(indexBuffer.length);
        myIndexBuffer.put(indexBuffer);
        myIndexBuffer.position(0);
    }


    // need to add functionality to only draw viewable/outside textures
    public void draw(GL10 gl, int[] texture)
    {
        // enable vertex and texture states
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // set the font face rotation
        gl.glFrontFace(GL10.GL_CW);

        // set the pointers to the buffers
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, myTexBuffer);

        // step each face of the cube and attach a different texture to each side
        for (int i = 0; i < 6; i++)
        {
            gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[i]); // bind the textures
            myIndexBuffer.position(6 * i);                    // step through the buffer
            gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, myIndexBuffer);
        }

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
    }
}

来自catlog的错误消息的前几行是:

JNI DETECTED ERROR IN APPLICATION:无效元素指针0x12ce4382,数组元素为0x12ce437c

in call to ReleaseArrayElements

from void com.google.android.gles_jni.GLImpl.glDrawElements(int, int, int, java.nio.Buffer)

&#34; GLThread 147&#34; prio = 5 tid = 12 Runnable

|基团=&#34;主&#34; sCount = 0 dsCount = 0 obj = 0x12c72430 self = 0xae286400

| sysTid = 2100 nice = 0 cgrp =默认sched = 0/0 handle = 0xb4559f00

| state = R schedstat =(0 0 0)utm = 1 stm = 16 core = 0 HZ = 100

| stack = 0xa6832000-0xa6834000 stackSize = 1036KB

|持有互斥锁=&#34; mutator lock&#34;(共享持有)

它通过for循环OK的第一次迭代。应用程序在第二次传递时崩溃了glDrawElements行。为什么这与KitKat Android 4.4没有任何障碍,并与Lollipop,Android 5.0崩溃?为了让我的代码与Lollipop一起工作,我需要做些什么?

1 个答案:

答案 0 :(得分:0)

使用allocateDirect分配索引缓冲区:

myIndexBuffer = ByteBuffer.allocateDirect(indexBuffer.length);

传递给OpenGLES的所有缓冲区都应该是直接缓冲区。我不知道为什么它可以在Kit Kat上运行,也许在幕后进行了优化,现在它有所作为。