有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在OpenGL ES 2中创建和使用VBOs

我正在寻求有关了解VBO的帮助。我已经做了大量的研究,找到了关于这个主题的教程,但它们对我来说仍然很模糊。我有几个问题:

VBO应该在哪里创建,我应该如何创建

我目前正在使用下面的代码初始化顶点和索引缓冲区:

    vertices = new float[]
            {
                    p[0].x, p[0].y, 0.0f,
                    p[1].x, p[1].y, 0.0f,
                    p[2].x, p[2].y, 0.0f,
                    p[3].x, p[3].y, 0.0f,
            };

    // The order of vertex rendering for a quad
    indices = new short[] {0, 1, 2, 0, 2, 3};

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

    ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(indices);
    drawListBuffer.position(0);

如果我是正确的,这不是创建VBO。那么,如果我想创建一个VBO,创建VBO的代码会紧跟在上面列出的代码之后吗?如果是,将如何创建

另外,VBO是如何渲染和绘制到屏幕的

它的渲染和绘制方式是否与仅使用顶点和索引数组相同?如果没有,过程是什么?目前,我渲染和绘制对象,如下代码所示:

    GLES20.glUseProgram(GraphicTools.sp_SolidColor);

    mPositionHandle =
            GLES20.glGetAttribLocation(GraphicTools.sp_SolidColor, "vPosition");

    GLES20.glEnableVertexAttribArray(mPositionHandle);

    GLES20.glVertexAttribPointer(mPositionHandle, 3,
            GLES20.GL_FLOAT, false,
            0, vertexBuffer);

    mtrxHandle = GLES20.glGetUniformLocation(GraphicTools.sp_SolidColor,
            "uMVPMatrix");

    GLES20.glUniformMatrix4fv(mtrxHandle, 1, false, m, 0);

    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
            GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

    GLES20.glDisableVertexAttribArray(mPositionHandle);

如果有任何问题,请告诉我。提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    AVertex Buffer Object是一个缓冲区,可以在其中存储顶点数组数据。这些数据一次性上传到图形内存(GPU)中,可重复用于绘制网格

    首先,必须创建两个缓冲区对象,一个用于顶点,一个用于索引:

    int buffers[] = new int[2];
    GLES20.glGenBuffers(2, buffers, 0);
    int vbo = buffers[0];
    int ibo = buffers[1];
    

    然后必须绑定缓冲区并传输数据

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo);
    GLES20.glBufferData(
        GLES20.GL_ARRAY_BUFFER,
        vertexBuffer.capacity() * 4, // 4 = bytes per float
        vertexBuffer,
        GLES20.GL_STATIC_DRAW);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo);
    GLES20.glBufferData(
        GLES20.GL_ELEMENT_ARRAY_BUFFER,
        drawListBuffer.capacity() * 2, // 2 = bytes per short
        drawListBuffer,
        GLES20.GL_STATIC_DRAW);
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
    

    如果要绘制网格,则必须定义通用顶点属性数据的数组,并且必须绑定索引缓冲区,但不必将任何数据传输到GPU:

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo);
    GLES20.glVertexAttribPointer(
            mPositionHandle, 3,
            GLES20.GL_FLOAT, false,
            0, 0);                        // <  - 0, because "vbo" is bound
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo);
    GLES20.glDrawElements(
        GLES20.GL_TRIANGLES, indices.length,
        GLES20.GL_UNSIGNED_SHORT, 0);     // <  - 0, because "ibo" is bound
    
    GLES20.glDisableVertexAttribArray(mPositionHandle);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
    


    另见An Introduction to Vertex Buffer Objects (VBOs)