opengl es 3.0学习笔记(基础向,持续更新)

这篇博客主要探讨OpenGL ES 3.0中的顶点着色器颜色属性输入问题和顶点缓冲区对象的使用。讲解了GL_ARRAY_BUFFER和GL_ELEMENT_ARRAY_BUFFER的作用,以及不同缓冲区模式对性能的影响。还介绍了顶点数组对象(VAO)提高效率的原理,并强调了glEnableVertexAttribArray在启用顶点着色器属性的重要性。文章中通过示例代码展示了正方体旋转的实现,同时提到了背面剔除功能以优化性能。

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

1.顶点着色器中的颜色属性的输入问题

//***********************不使用顶点缓冲区对象时******************//
//设置顶点着色器中的颜色属性
GLfloat color[4 * 4] = {
	1.0f, 0.0f, 0.0f, 1.0f,   // c0
};

//顶点着色器读取颜色,这里的1对应顶点着色器中color对应的location
glVertexAttrib4fv(1, color);




//************************使用顶点缓冲区对象时******************//
GLfloat color[4 * 4] = {
	1.0f, 0.0f, 0.0f, 1.0f,   // c0
	0.0f, 1.0f, 0.0f, 1.0f,   // c1
	0.0f, 0.0f, 1.0f, 1.0f    // c2
};

//初始化操作,将颜色值读取到缓冲区对象中
glGenBuffers(3, userData->vboId);
glBindBuffer(GL_ARRAY_BUFFER, userData->vboId[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 16, color, GL_STATIC_DRAW);

//渲染图像时,从缓冲区洪读取数据操作
glBindBuffer(GL_ARRAY_BUFFER, userData->vboId[1]);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);

GL_ARRAY_BUFFER:标志指定的数组缓冲区对象用于创建保存顶点数据的缓冲区对象;

GL_ELEMENT_ARRAY_BUFFER:标志指定的元素数组缓冲区对象,用于创建保存图元索引的缓冲区对象;

 

GL_STATIC_DRAW:缓冲区对象数据将被修改一次,使用多次,以绘制图元或者指定图像;

GL_STATIC_READ:缓冲区对象数据将被修改一次,使用多次,以从opengl es读回数据;从opengl es读回的数据将从应用程序中查询;

GL_STATIC_COPY:缓冲区对象数据将被修改一次,使用多次,以从opengl es读回数据;从opengl es读回的数据将直接用作绘制图元或者修改图像信息的来源;

GL_DYNAMIC_DRAW:缓冲区对象数据将被重复修改,使用多次,以绘制图元或者指定图像;

GL_STREAM_DRAW:缓冲区对象数据将被修改一次,只使用少数几次,以绘制图元或者指定图像;

 

如果使用缓冲区模式来读取颜色值,那么颜色对应的数据大小必须和顶点数据大小一致(即假设有三个顶点,那么就必须有三个颜色与其对应,否则系统将自动默认颜色为黑色,补齐),这种操作会出现两个顶点的中间位置处出现颜色的渐变现象。

使用顶点缓冲区对象可以减少CPU和GPU之间复制的数据量,从而获得更好的性能。

opengl es 3.0推出了顶点数组对象(VAO),VAO提供包含在顶点数组/顶点缓冲区对象配置之间切换所需要的所有状态的单一变量;使用顶点缓冲区对象设置绘图操作需要多次调用glBindBuffer,glVertexAttribPointer,glEnableVertexAttribArray等,而VAO正是解决这个问题的,提高整体运行效率!!

//初始化部分
	glGenBuffers(3, userData->vboId);
	glBindBuffer(GL_ARRAY_BUFFER, userData->vboId[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 24, vertexPos, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, userData->vboId[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 32, color, GL_STATIC_DRAW);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->vboId[2]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 24, indices, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	glGenVertexArrays(1, &userData->vaoId);
	glBindVertexArray(userData->vaoId);

	glBindBuffer(GL_ARRAY_BUFFER, userData->vboId[0]);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);

	glBindBuffer(GL_ARRAY_BUFFER, userData->vboId[1]);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->vboId[2]);

	//glDisableVertexAttribArray(0);
	//glDisableVertexAttribArray(1);

	glBindVertexArray(0);





//绘图部分
	glBindVertexArray(userData->vaoId);
	glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, 0);
	glBindVertexArray(0);

glEnableVertexAttribArray:默认情况下,出于性能考虑,所有顶点着色器的属性(Attribute)变量都是关闭的,意味着数据在着色器端是不可见的,哪怕数据已经上传到GPU,由glEnableVertexAttribArray启用指定属性,才可在顶点着色器中访问逐顶点的属性数据。glVertexAttribPointer或VBO只是建立CPU和GPU之间的逻辑连接,从而实现了CPU数据上传至GPU。但是,数据在GPU端是否可见,即,着色器能否读取到数据,由是否启用了对应的属性决定,这就是glEnableVertexAttribArray的功能,允许顶点着色器读取GPU(服务器端)数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值