Android基于OpenGL ES 3.0的VBO,VAO,EBO的使用(NDK开发)

有过一点OpenGL开发经验的人就知道每次绘图之前都会绑定顶点数组,每次将一个顶点传到GPU进行绘制。但是从CPU传数据到GPU的效率并不高,所以我们就需要使用VBO顶点缓存对象来一次性传递多个顶点到GPU,而VAO是3.0以后的版本才有的功能,它允许我们保存对于顶点的配置信息,我们配置好之后就只需要绑定对应的VAO,然后直接绘制即可。索引缓冲对象EBO和VBO类似也就是保存下标的缓冲。
- 顶点数组对象:Vertex Array Object,VAO
- 顶点缓冲对象:Vertex Buffer Object,VBO
- 索引缓冲对象:Element Buffer Object

下面就简单实用这三个东西来绘制一个三角形和一个矩形。

EGL环境初始化

这里我就不多说了,可以看我之前的文章关于Android端EGL环境
这里注意的一点是需要注意API的版本,但是我在手机上测试实用2也能用,这就很尴尬了。

 EGLint eglContextAttribute[] = {
            EGL_CONTEXT_CLIENT_VERSION, 3,
            EGL_NONE
    };
    if (!(context = eglCreateContext(display, config,
                                     NULL == sharedContext ? EGL_NO_CONTEXT : sharedContext,
                                     eglContextAttribute))) {
        LOGE("eglCreateContext() returned error %d", eglGetError());
        release();
        return false;
    }
着色器

绘制三角形和矩形的着色器都十分简单,直接贴上。3.0的GLSL使用in代替了attribute,out代替varying。片元着色器的out就是制定颜色输出了。

1、vertex_shader.glsl
#version 300 es
layout (location = 0) in vec3 aPos;
void main(){
   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
2、fragment_shader.glsl
#version 300 es
 out vec4 FragColor;
 void main(){
     FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
 }

绘制流程

1、绘制三角形

(1) VAO,VBO的配置

float vertices[] = {
            -0.5f, -0.0f, 0.0f, // left
            0.5f, -0.0f, 0.0f, // right
            0.0f, 1.0f, 0.0f  // top
    };
    VAO = new GLuint[2];
    VBO = new GLuint[2];
    //生成两个VAO和两个VBO
    glGenVertexArrays(2, VAO);
    glGenBuffers(2, VBO);
    //绑定第一个VAO
    glBindVertexArray(VAO[0]);
    //绑定第一个VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    //GL_STATIC_DRAW表示顶点不会变化,绑定数组
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    //指定解析顶点规则
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
    glEnableVertexAttribArray(0);
    //解绑
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

这里我们初始化了两个VAO和两个VBO,因为后面需要一个矩形,然后绑定之后将顶点数据绑定到VBO,同时指定解析顶点规则,这样就可以将这些规则保存到响应的VAO中,最后我们解绑。

(2)三角形的绘制
一切配置完成后三角形绘制就很简单了,除了初始化,我们只需要绑定VAO然后绘制一个三角形就可以了。

  glViewport(_backingLeft, _backingTop, _backingWidth, _backingHeight);
    //设置一个颜色状态
    glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
    //使能颜色状态的值来清屏
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glUseProgram(program);
    glBindVertexArray(VAO[0]);
    glDrawArrays(GL_TRIANGLES, 0, 3);
2、绘制矩形

(1)VAO,VBO,EBO的配置
和之前很类似,这次需要额外绑定一个EBO,然后这些信息同样会保存在对应VAO中。

  unsigned int indices[] = { // 注意索引从0开始!
            0, 1, 3, // 第一个三角形
            1, 2, 3  // 第二个三角形
    };
    glGenBuffers(1, &EBO);
    glBindVertexArray(VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
    //绑定索引EBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    //绑定索引数组
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    //指定解析顶点规则
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);

(2)绘制矩形
最后的绘制同样只需要绑定VAO来绘制就可以了

    glBindVertexArray(VAO[1]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

源码地址
参考资料:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/

猜你喜欢

转载自blog.csdn.net/a568478312/article/details/80467469