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

How to create and use VBOs in OpenGL ES 2(如何在 OpenGL ES 2 中创建和使用 VBO)
本文介绍了如何在 OpenGL ES 2 中创建和使用 VBO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻求有关理解 VBO 的帮助.我已经进行了大量研究并找到了有关该主题的教程,但它们对我来说仍然含糊不清.我有几个问题:

I am looking for help with understanding VBOs. I have done a ton of research and have found tutorials on the subject, but they are still vague to me. I have a few questions:

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

Where should a VBO be created, and how should I create one?

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

I am currently using the code right below to initialize my vertex and index buffers:

    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 的代码会紧跟上面列出的代码吗?如果有,如何创建?

If I am correct, this is not creating a VBO. So, if I wanted to make a VBO, would the code to create a VBO go right after the code listed above? If so, how would it be created?

另外,如何将 VBO 渲染和绘制到屏幕上?

Also, how is a VBO rendered and drawn to screen?

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

Is it rendered and drawn the same way as just using vertex and index arrays? If not, what is the process? Currently, I render and draw my objects as shown in the code below:

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

如果您有任何问题,请告诉我.提前致谢.

If you have any questions, let me know. Thanks in advance.

推荐答案

A 顶点缓冲区Object 是一个可以存储顶点数组数据的缓冲区.数据一次性上传到图形内存(GPU),可重复用于绘制网格.

A Vertex Buffer Object is a buffer where vertex array data can be stored. The data are uploaded one time to the graphics memory (GPU) and can be used repeatedly to draw a mesh.

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

First you have to create 2 buffer objects, one for the vertices and one for the indices:

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

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

Then you have to bind the buffer and to transfer the data

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:

If you want to draw the mesh, then you have to define the array of generic vertex attribute data and you have to bind the index buffer, but you don't have to transfer any data to the 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);


另见 顶点缓冲区简介对象(VBO)

这篇关于如何在 OpenGL ES 2 中创建和使用 VBO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

OpenGl error Validation Failed: No vertex array object bound(OpenGL错误验证失败:未绑定顶点数组对象)
Why do I get error INVALID_OPERATION when I call glMultiDrawElementsIndirect(为什么在调用glMultiDrawElementsInDirect时出现INVALID_OPERATION错误)
find out instantiating object in the constructor of a class(在类的构造函数中找出实例化对象)
Implementing trapezoidal sprites in LibGDX(在 LibGDX 中实现梯形精灵)
Drawing a gradient in Libgdx(在 Libgdx 中绘制渐变)
OpenGL is not supported by the video driver(视频驱动程序不支持 OpenGL)