OpenGL超级宝典(第7版)笔记6 顶点属性 着色器间数据传输 接口块 稍微介绍一下VAO 清单3.1-3.4

OpenGL超级宝典(第7版)笔记6 VAO顶点数组究竟是啥 清单3.1-3.4


上一次我们带大家绘制了第一个三角形,给这篇的着色器数值传递做了预热,稍微解释了一下插值,当然我们还留了个小问题,是关于人眼观察到的颜色的小特性。

这一篇我们将初步的解释一下顶点数组对象(VAO)究竟是干什么的。当然你要注意我会先介绍一个叫:顶点属性 的概念,这和顶点数组对象并不是一个东西,但它们是相关的。介绍完顶点属性之后我们再介绍顶点数组对象。

1 关于顶点属性

虽然上一次我们绘制出了第一个三角形,但是这也引发了一些问题需要我们改进。我们的顶点位置数据是写在着色器(shader)中的,也就是说我们每次想修改顶点的位置必须修改着色器中的数值(显然这样做并不灵活,因为目前为止我们的顶点时固定的位置,以后我们顶点的位置可能要根据输入的不同而改变)。其次如果我们有大量的三角形要显示,那么着色器程序就会变得很大,这不利于着色器的调用(会变慢),我们希望能从其他地方提供顶点数据给着色器,着色器从这些数据中按我们设定的规则提取数据,把它们作为顶点数据来进行运算。顶点属性作为着色器接受数据的接口,就是起到接受顶点数据的作用的。

1.1顶点属性声明 清单3.1

清单3.1顶点属性声明

#version 450 core
layout (location = 0) in vec4 offset;
//这里每次运行的时候接受4个GLfloat作为vec4 offset的值
//假如从location = 0这个端口位置传入的是(0.1f,0.0f,0.0f,0.0f)
	//那么顶点的位置会向右挪0.1f
void main(void){
   
	const vec4 vertices[3] = vec4[3](
	vec4(0.25,-0.25,0.5,1.0),
	vec4(-0.25,-0.25,0.5,1.0),
	vec4(0.25,0.25,0.5,1.0));
	gl_Position = vertices[gl_VertexID]+offset;
}

上面的顶点着色器会在运行的时候从0号端口(location = 0)按照之前我们设定的规则在指定的位置(或是函数)中提取所需的数值(这里是vec4,就是4个GLfloat组成的数组,这里用来表示xyzw)。
当然上面的提取规则就是通过顶点数组对象(VAO)来实现的(等一下再说)。

1.2顶点属性更新 清单3.2

那么怎么将数据传到着色器中,精确的说是传到(location = 0)这个位置上去呢,清单3.2 更新顶点属性

void render(
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用着色器画线,需要先定义一个顶点着色器和一个片段着色器顶点着色器代码如下: ``` #version 330 core layout (location = 0) in vec3 aPos; void main() { gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); } ``` 这个着色器只有一个输入变量 `aPos`,表示每个顶点的位置,然后将位置信息传递给 `gl_Position`,生成裁剪空坐标。 接下来是片段着色器代码: ``` #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); } ``` 这个着色器只有一个输出变量 `FragColor`,表示片段的颜色。这里将所有片段的颜色设为白色。 接下来,我们需要定义线的顶点坐标和顶点索引: ``` float vertices[] = { -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f }; unsigned int indices[] = { 0, 1 }; ``` 这里定义了两个顶点,分别是 (-0.5, 0.0, 0.0) 和 (0.5, 0.0, 0.0),然后定义了一个线的顶点索引,表示这两个顶点组成了一条线。 接下来,我们需要创建 VAO、VBO 和 EBO,并将数据传递给它们: ``` unsigned int VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 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); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); ``` 这里先生成了 VAO、VBO 和 EBO 的 ID,然后绑定 VAO,绑定 VBO 并将顶点数据传递给它,绑定 EBO 并将顶点索引数据传递给它,然后设置 VAO属性指针,并启用它们。最后解绑 VBO 和 VAO。 接下来,我们需要绘制这条线: ``` glUseProgram(shaderProgram); glBindVertexArray(VAO); glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, 0); glBindVertexArray(0); ``` 这里先使用着色器程序 `shaderProgram`,然后绑定 VAO,使用 `glDrawElements` 函数绘制线,最后解绑 VAO。 这样,我们就成功使用着色器画了一条线。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值