当前位置: 首页 > 面试题库 >

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

姜振濂
2023-03-14
问题内容

我正在寻求了解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);

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


问题答案:

甲顶点缓存对象是其中顶点数组的数据可以被存储在缓冲器中。数据一次上传到图形内存(GPU),并且可以重复用于绘制网格。

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

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

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



 类似资料:
  • 关于色板 色板 是命名的颜色、色调、渐变和图案。与文档相关联的色板出现在“色板”面板中。色板可以单独出现,也可以成组出现。 可以打开来自其他 Illustrator 文档和各种颜色系统的色板库。色板库显示在单独的面板中,不与文档一起存储。 “色板”面板和色板库面板可包括以下类型的色板: 印刷色 印刷色使用四种标准印刷色油墨的组合打印:青色、洋红色、黄色和黑色。默认情况下,Illustrator 将

  • 我正在尝试使用guice,我想在JavaPlay2.6中创建一个单例随机webservice客户端 现在我有了WS-client,它作为java播放模块加载。当我运行应用程序时,没有问题,我的客户机能够使用java play配置(),这是注入的。但是如果我尝试在其他任何地方使用我的客户机,我会得到一个错误,说。 这是我的(非常简单的)客户: 实现Guice的AbstractModule的我的模块:

  • 我想用PHP在MySQL数据库中创建一个表。这是我的尝试: 但这给了我一个错误 我搜索了很多,但没有找到成功的解决方案。有人有主意吗?

  • 我正在用javafx设计一个独立的应用程序(带有scenebuilder 8的FXML),现在我需要在FXML中创建一个CheckBoxTreeItem(查看下图)。 方格树 在搜索时,我得到了一个链接“https://docs.oracle.com/javase/8/scene-builder-2/user-guide/library-panel.htm这有助于我将定制的CheckBoxTree

  • 我试图创建一个数据网格——或者在angular2中用JSON对象创建一个表格。我的问题是我不知道表中有多少列,也不知道这些列的名称。 从我目前的理解我需要定义世界卫生大会 也许一个例子会让事情变得更清楚。。。 下面是我需要在同一个表中呈现的两个JSON示例... 示例1 示例 2 这里有我的组件… 表格: 应用程序字段映射行: 注意:这是我卡住的地方! 我如何创建正确的数量的细胞和h 我没能找到任

  • 我想在我的游戏日期控制器中使用find_or_create方法。当参数在game_date_params时,我不知道如何在创建动作中使用该方法。任何建议如何从game_date_params中提取日期? 这是POST操作的输出: 2016-04-01 10:21:44 0200开始POST“/game_dates”127.0.0.1由GameDatesController#创建为HTML参数:{“