生成球体时的空指针

时间:2015-06-05 13:11:58

标签: android opengl-es nullpointerexception

我试图在opengl es 2.0中创建一个球体但我得到一个空指针异常。我已经坚持了几个小时。在检查logcat后,它似乎找到了几个顶点但是后面的索引缓冲区总是直接命中空指针。

 private void generateSphereCoords(float radius, int stacks, int slices) {
    for (int stackNumber = 0; stackNumber <= stacks; stackNumber++) {
        for (int sliceNumber = 0; sliceNumber <= slices; sliceNumber++) {
            float theta = (float) (stackNumber * Math.PI / stacks);
            float phi = (float) (sliceNumber * 2 * Math.PI / slices);
            Log.i("theta", String.valueOf(theta));
            Log.i("phi", String.valueOf(phi));
            float sinTheta = FloatMath.sin(theta);
            float sinPhi = FloatMath.sin(phi);
            float cosTheta = FloatMath.cos(theta);
            float cosPhi = FloatMath.cos(phi);
            vertices = new float[]{radius * cosPhi * cosTheta, radius * sinPhi * cosTheta, radius * sinTheta};
            Log.i("vertexX", String.valueOf(vertices[0]));
            Log.i("vertexY", String.valueOf(vertices[1]));
            Log.i("vertexZ", String.valueOf(vertices[2]));
            // a float is 4 bytes, therefore I multiply the number of vertices by 4.
            ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);// (number of coordinate values * 4 bytes per float)
            vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order
            vertexBuffer = vbb.asFloatBuffer();// create a floating point buffer from the ByteBuffer
            vertexBuffer.put(vertices);
            vertexBuffer.position(0);// set the buffer to read the first coordinate
        }
    }

    for (int stackNumber = 0; stackNumber <= stacks; stackNumber++) {
        for (int sliceNumber = 0; sliceNumber <= slices; sliceNumber++) {
            ByteBuffer ibb = ByteBuffer.allocateDirect(vertexCount * 2);// (number of coordinate values * 4 bytes per float)
            ibb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order
            indexBuffer = ibb.asShortBuffer();// create a floating point buffer from the ByteBuffer
            indexBuffer.put((short) ((stackNumber * slices) + (sliceNumber % slices)));
            indexBuffer.put((short) (((stackNumber + 1) * slices) + (sliceNumber % slices)));
            indexBuffer.position(0);// set the buffer to read the first coordinate
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在循环外部创建顶点缓冲区和索引缓冲区。因为它是为每个顶点重建顶点缓冲区和为每对索引重建索引缓冲区。

private static final int VERTICES_PER_COORD = 3;
private void generateSphereCoords(float radius, int stacks, int slices) {

    // Create vertex buffer here:
    ByteBuffer vbb = ByteBuffer.allocateDirect((stacks + 1) * (slices + 1) * VERTICES_PER_COORD * 4);// (number of coordinate values * 4 bytes per float)
    vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order
    vertexBuffer = vbb.asFloatBuffer();// create a floating point buffer from the ByteBuffer

    for (int stackNumber = 0; stackNumber <= stacks; stackNumber++) {
        for (int sliceNumber = 0; sliceNumber <= slices; sliceNumber++) {
            float theta = (float) (stackNumber * Math.PI / stacks);
            float phi = (float) (sliceNumber * 2 * Math.PI / slices);
            Log.i("theta", String.valueOf(theta));
            Log.i("phi", String.valueOf(phi));
            float sinTheta = FloatMath.sin(theta);
            float sinPhi = FloatMath.sin(phi);
            float cosTheta = FloatMath.cos(theta);
            float cosPhi = FloatMath.cos(phi);
            vertices = new float[]{radius * cosPhi * cosTheta, radius * sinPhi * cosTheta, radius * sinTheta};
            Log.i("vertexX", String.valueOf(vertices[0]));
            Log.i("vertexY", String.valueOf(vertices[1]));
            Log.i("vertexZ", String.valueOf(vertices[2]));
            // a float is 4 bytes, therefore I multiply the number of vertices by 4.

            // add this vertex tp the buffer:        
            vertexBuffer.put(vertices);                
        }
    }
    vertexBuffer.position(0);// set the buffer to read the first coordinate

    // Create index buffer here:
    ByteBuffer ibb = ByteBuffer.allocateDirect((stacks + 1) * (slices + 1) * 2 * 2);// (number of index values * 2 bytes per short)
    ibb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order
    indexBuffer = ibb.asShortBuffer();// create a floating point buffer from the ByteBuffer

    for (int stackNumber = 0; stackNumber <= stacks; stackNumber++) {
        for (int sliceNumber = 0; sliceNumber <= slices; sliceNumber++) {                
            indexBuffer.put((short) ((stackNumber * slices) + (sliceNumber % slices)));
            indexBuffer.put((short) (((stackNumber + 1) * slices) + (sliceNumber % slices)));                
        }
    }
    indexBuffer.position(0);// set the buffer to read the first index
}