Android VBO / IBO无法正常工作

时间:2013-08-04 15:49:17

标签: android opengl-es-2.0

目前我正在开发适用于Android的3D游戏引擎。该项目刚刚开始,但有一个问题我无法解决。 我想使用VertexBufferObjects来渲染从.obj文件加载的模型。 这是代码

public class Mesh {

    private final int mBytesPerFloat = 4;

    private FloatBuffer vertices;
    private FloatBuffer normals;
    private IntBuffer faces;

    private int vertexBuffer;
    private int normalBuffer;
    private int indexBuffer;

    public Mesh(float[] vertices, float[] normals, int[] faces, int shaderProgram) {

        this.normals = ByteBuffer.allocateDirect(normals.length * mBytesPerFloat)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        this.normals.put(normals).position(0);

        this.faces = ByteBuffer.allocateDirect(faces.length * mBytesPerFloat)
                .order(ByteOrder.nativeOrder())
                .asIntBuffer();
        this.faces.put(faces).position(0);

        this.vertices = ByteBuffer.allocateDirect(vertices.length * mBytesPerFloat)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        this.vertices.put(vertices).position(0);

        ByteBuffer bb = ByteBuffer.allocateDirect(8);
        bb.order(ByteOrder.nativeOrder());
        IntBuffer buffer = bb.asIntBuffer();        
        GLES20.glGenBuffers(1, buffer);
        vertexBuffer = buffer.get(0);       

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, this.vertices.capacity() * mBytesPerFloat, this.vertices, GLES20.GL_STATIC_DRAW);

        bb = ByteBuffer.allocateDirect(8);
        bb.order(ByteOrder.nativeOrder());
        buffer = bb.asIntBuffer();      
        GLES20.glGenBuffers(1, buffer);
        normalBuffer = buffer.get(0);
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, normalBuffer);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, this.normals.capacity() * mBytesPerFloat, this.normals, GLES20.GL_STATIC_DRAW);

        bb = ByteBuffer.allocateDirect(8);
        bb.order(ByteOrder.nativeOrder());
        buffer = bb.asIntBuffer();      
        GLES20.glGenBuffers(1, buffer);
        indexBuffer = buffer.get(0);
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
        GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.faces.capacity() * mBytesPerFloat, this.faces, GLES20.GL_STATIC_DRAW);
    }

    public Mesh() {
        // TODO Auto-generated constructor stub
    }

    public void render(int shaderProgram) {
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
        GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(shaderProgram, "vertex"), 3, GLES20.GL_FLOAT, false, 0, 0);
        GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(shaderProgram, "vertex"));
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, normalBuffer);
        GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(shaderProgram, "normal"), 3, GLES20.GL_FLOAT, false, 0, 0);
        GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(shaderProgram, "normal"));
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);       
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, vertices.capacity()/3, GLES20.GL_INT, faces);
    }
}

问题是我什么都没看到。 问题不在于我使用的着色器(我知道它正常工作)并且模型视图矩阵和投影矩阵是正确的,因此对象应该是可见的,如果它被渲染它不是。 有谁知道问题可能是什么?

1 个答案:

答案 0 :(得分:1)

glDrawElements似乎不接受GL_INT作为数据类型,因此glDrawElements调用可能会失败(可能很容易通过一些简单的glGetError进行检查为了调试而调用)。只需尝试GL_UNSIGNED_INT代替(UIntBuffer代替faces或类似内容(如果存在)。

也许它在ES中甚至没有GL_UNSIGNED_INT,你需要2字节GL_UNSIGNED_SHORT,但我不确定。但你肯定需要一个无符号类型(签名类型对索引有什么意义呢?但是好吧,那就是 Java )。无论如何,一些glGetError可能会在这里创造奇迹。