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);
    }
}

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

4

1 回答 1

1

它似乎不像glDrawElements接受GL_INT作为数据类型,所以调用可能只是失败(为了调试glDrawElements,这可能很容易通过一些简单的调用进行检查)。glGetError只是尝试(如果存在GL_UNSIGNED_INT,可能是UIntBufferfor或类似的东西)。faces

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

于 2013-10-07T15:32:10.783 回答