关于OpenGL利用VBO绘制以及VBO和VAO的关系

本文介绍了OpenGL中的顶点数组对象(VAO)和顶点缓冲对象(VBO),阐述了它们在图形渲染中的作用。VBO用于存储顶点数据,提高数据传输效率,而VAO则用来描述数据并管理多个VBO。文章通过代码示例展示了如何创建和使用VBO与VAO,并强调了在类实现中注意数组大小的重要性,以避免编程错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于OpenGL利用VBO绘制以及VBO和VAO的关系

前言

VBOVAO是OpenGL中非常重要的概念,这里先解释一下是什么意思:

顶点数组对象:Vertex Array Object,VAO
顶点缓冲对象:Vertex Buffer Object,VBO

初学者很容易弄错两者的关系 刚开始我也弄错了QAQ,这里就来详细解释一下:

VBO

  全称Vertex Buffer Object,是用来储存顶点数据的,我们知道:将数据从CPU发送到显卡是非常慢的,所以,就需要这样一个东西,将顶点数据一次性发送到显卡,提高渲染的效率,创建VBO的流程大概是这样的:

glGenBuffers(1, &VBO); // 创建一个VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO); // 绑定顶点数据缓存空间
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 发送数据

  这里简单说一下:GL_ARRAY_BUFFER 指的是OpenGL提供的几种缓冲区中的一种,类似比较常用的还有:GL_ELEMENT_ARRAY_BUFFER ,这些缓冲区是用来缓存待发送的数据的,当数据全部复制到缓冲区GL_ARRAY_BUFFER ~(即 glBindBuffer(GL_ARRAY_BUFFER, VBO); )~ 之后,再通过 glBufferData 发送数据到显卡上,这样就完成了一次高效的数据传输。

VAO

  接着就是 Vertex Array Object ,我们用VBO向显卡发送了数据,但是显卡并不知道这些数据是干嘛的,以及怎么使用这些数据,这时候就需要VAO来描述这些数据了,VAO还有一个好处,一个VAO可以对应多个VBO,这样绘制起来就很方便。

注意:OpenGL的核心模式要求我们使用VAO,所以它知道该如何处理我们的顶点输入。如果我们绑定VAO失败,OpenGL会拒绝绘制任何东西。

同样,创建一个VAO也很简单:

glGenVertexArrays(1, &VAO); // 创建一个VAO
glBindVertexArray(VAO);	// 绑定VAO
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // 利用VAO描述顶点属性
glEnableVertexAttribArray(0);	// 启用着色器中的顶点属性

整合

  将上面所说的整合成一个类就是这样的:

注:BasicShader是用来编译着色器的。

class BasicDraw
{
public:
	~BasicDraw() {
		glDeleteVertexArrays(1, &VAO);
		glDeleteBuffers(1, &VBO_Vertex);
		glDeleteBuffers(1, &VBO_color);
	}

	// 初始化绘图==>创建VAO
	unsigned int Get_STATIC_VAO(float vertices[],int size_vertices, float color[], int size_color) {
		// 创建VBO和VAO
		glGenVertexArrays(1, &VAO);
		glGenBuffers(1, &VBO_Vertex); // 创建顶点和颜色的VBO
		glGenBuffers(1, &VBO_color);

		// 绑定VAO,这代表解绑这钱所有数据都会存到这个VAO中
		glBindVertexArray(VAO);

		// 提交数据
		/* 顶点VBO */
		glBindBuffer(GL_ARRAY_BUFFER, VBO_Vertex); // 绑定顶点数据缓存空间
		glBufferData(GL_ARRAY_BUFFER, size_vertices, vertices, GL_STATIC_DRAW);
		
		// 解析VBO中的数据
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
		// 启用顶点属性==>即着色器中(location=0)的顶点属性
		glEnableVertexAttribArray(0);

		/* 颜色VBO */
		glBindBuffer(GL_ARRAY_BUFFER, VBO_color);
		glBufferData(GL_ARRAY_BUFFER, size_color, color, GL_STATIC_DRAW);
		glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
		glEnableVertexAttribArray(1);

		// 解绑VBO==>因为已经将数据发送到显卡了,所以可以安全的解绑
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		// 解绑VAO
		glBindVertexArray(0);

		return VAO;
	}
private:
	unsigned int VBO_Vertex, VBO_color, VAO;
};

顶点数据

	float vertices[] = {
	-0.5f, -0.5f, 0.0f, // left  
	 0.5f, -0.5f, 0.0f, // right 
	 0.0f,  0.5f, 0.0f  // top   
	};

	GLfloat colors[] = {
	1.0f, 0.0f, 0.0f, 1.0f,
	0.0f, 1.0f, 0.0f, 1.0f,
	0.0f, 0.0f, 1.0f, 1.0f
	};

特别注意!

  如果是通过类来实现绘制功能,需要在参数里加上数组的大小,不然就会找俩小时错误都不知道错在哪QAQ,因为sizeof(ptr)一定是8字节,所以一定会出错!!!学的教训啊QAQ

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值