返回

游戏引擎从零开始:抽象封装VertexArray,告别OpenGL直接调用!

Android

Vertex Array Object:优化 OpenGL 应用程序的宝贵工具

一、VertexArray 是什么?

VertexArray Object (VAO) 是一种 OpenGL 对象,用于存储顶点属性指针和顶点缓冲对象 (VBO) 的引用。它充当了顶点数据的容器,在渲染对象时无需重复绑定 VBO 和设置属性指针。只需要绑定 VAO,就可以将顶点数据有效地发送到图形流水线。

二、为什么要抽象封装 VertexArray?

对 VertexArray 进行抽象封装,可以将应用程序中对 OpenGL 的直接调用转移到渲染器层,带来诸多优势:

  • 代码的可读性: 通过抽象封装,应用程序不必直接调用 OpenGL API,而是通过更高级别的接口操作 VAO。这显著提高了代码的可读性和可维护性。
  • 性能提升: 抽象封装减少了应用程序与驱动程序之间的通信次数,从而提升了性能。
  • 灵活性: 抽象封装简化了切换不同渲染器的流程。如果应用程序需要从 OpenGL 切换到 DirectX,只需要修改渲染器层,而无需修改应用程序本身。

三、如何抽象封装 VertexArray?

抽象封装 VertexArray 有多种方法,我们推荐以下简单有效的步骤:

  1. 在渲染器层定义一个 VertexArray 类。
  2. 在 VertexArray 类中定义必要的成员变量和方法。
  3. 在应用程序中创建 VertexArray 对象,并将其绑定到渲染器。
  4. 在应用程序中设置 VAO 的顶点属性指针和 VBO 引用。
  5. 在应用程序中调用 glDrawArrays 或 glDrawElements 进行渲染。

四、VertexArray 的具体实现

class VertexArray {
public:
  VertexArray();
  ~VertexArray();

  void Bind();
  void Unbind();

  void SetVertexAttributePointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);

  void SetIndexBuffer(GLuint indexBufferObject);

private:
  GLuint m_VertexArrayObject;
  GLuint m_IndexBufferObject;
};

VertexArray::VertexArray() {
  glGenVertexArrays(1, &m_VertexArrayObject);
}

VertexArray::~VertexArray() {
  glDeleteVertexArrays(1, &m_VertexArrayObject);
}

void VertexArray::Bind() {
  glBindVertexArray(m_VertexArrayObject);
}

void VertexArray::Unbind() {
  glBindVertexArray(0);
}

void VertexArray::SetVertexAttributePointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer) {
  glBindVertexArray(m_VertexArrayObject);
  glVertexAttribPointer(index, size, type, normalized, stride, pointer);
}

void VertexArray::SetIndexBuffer(GLuint indexBufferObject) {
  glBindVertexArray(m_VertexArrayObject);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
}

使用 VertexArray 类的相关方法,可以轻松地设置顶点属性指针和 VBO 引用,以及绑定索引缓冲对象。

五、总结

抽象封装 VertexArray 将 OpenGL 的直接调用与应用程序分离,提升了代码的可读性、可维护性、性能和灵活性。通过采用本文介绍的方法,可以高效地利用 VertexArray Object,优化 OpenGL 应用程序。

常见问题解答

  1. 为什么使用 VAO 而不用直接绑定 VBO?

VAO 可以存储多个 VBO 和顶点属性配置,减少了绑定和配置 VBO 的开销。

  1. 如何创建和绑定 VAO?

使用 VertexArray 类创建 VAO,调用 Bind() 方法将其绑定到渲染器。

  1. 如何设置 VAO 的顶点属性指针?

调用 SetVertexAttributePointer() 方法设置顶点属性指针。

  1. 如何设置 VAO 的索引缓冲对象?

调用 SetIndexBuffer() 方法设置索引缓冲对象。

  1. 使用 VAO 有什么优势?

提高性能、简化代码、增加灵活性。