返回
游戏引擎从零开始:抽象封装VertexArray,告别OpenGL直接调用!
Android
2022-12-24 00:07:19
Vertex Array Object:优化 OpenGL 应用程序的宝贵工具
一、VertexArray 是什么?
VertexArray Object (VAO) 是一种 OpenGL 对象,用于存储顶点属性指针和顶点缓冲对象 (VBO) 的引用。它充当了顶点数据的容器,在渲染对象时无需重复绑定 VBO 和设置属性指针。只需要绑定 VAO,就可以将顶点数据有效地发送到图形流水线。
二、为什么要抽象封装 VertexArray?
对 VertexArray 进行抽象封装,可以将应用程序中对 OpenGL 的直接调用转移到渲染器层,带来诸多优势:
- 代码的可读性: 通过抽象封装,应用程序不必直接调用 OpenGL API,而是通过更高级别的接口操作 VAO。这显著提高了代码的可读性和可维护性。
- 性能提升: 抽象封装减少了应用程序与驱动程序之间的通信次数,从而提升了性能。
- 灵活性: 抽象封装简化了切换不同渲染器的流程。如果应用程序需要从 OpenGL 切换到 DirectX,只需要修改渲染器层,而无需修改应用程序本身。
三、如何抽象封装 VertexArray?
抽象封装 VertexArray 有多种方法,我们推荐以下简单有效的步骤:
- 在渲染器层定义一个 VertexArray 类。
- 在 VertexArray 类中定义必要的成员变量和方法。
- 在应用程序中创建 VertexArray 对象,并将其绑定到渲染器。
- 在应用程序中设置 VAO 的顶点属性指针和 VBO 引用。
- 在应用程序中调用 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 应用程序。
常见问题解答
- 为什么使用 VAO 而不用直接绑定 VBO?
VAO 可以存储多个 VBO 和顶点属性配置,减少了绑定和配置 VBO 的开销。
- 如何创建和绑定 VAO?
使用 VertexArray 类创建 VAO,调用 Bind() 方法将其绑定到渲染器。
- 如何设置 VAO 的顶点属性指针?
调用 SetVertexAttributePointer() 方法设置顶点属性指针。
- 如何设置 VAO 的索引缓冲对象?
调用 SetIndexBuffer() 方法设置索引缓冲对象。
- 使用 VAO 有什么优势?
提高性能、简化代码、增加灵活性。