OPENGL学习笔记之glEnableVertexAttribArray函数

本文探讨了OpenGL中glEnableVertexAttribArray函数的作用及其调用时机。该函数用于激活顶点属性,使得顶点着色器能够访问到GPU上的数据。默认情况下,所有顶点属性变量处于关闭状态,必须通过此函数手动开启。

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

OPENGL学习笔记之glEnableVertexAttribArray函数

2017/10/18

写代码画三角形的时候发现总是无法输出顶点的数据,查阅文档之后发现是因为不小心注释掉了glEnableVertexAttribArray(0);的问题,所以查阅相关资料如下:

本文档讨论glEnableVertexAttribArray的作用及调用位置问题。

当我们特别谈论到顶点着色器的时候,每个输入变量也叫顶点属性(Vertex Attribute)。我们能声明的顶点属性是有上限的,它一般由硬件来决定。OpenGL确保至少有16个包含4分量的顶点属性可用,但是有些硬件或许允许更多的顶点属性,你可以查询GL_MAX_VERTEX_ATTRIBS来获取具体的上限:

int nrAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;

通常情况下它至少会返回16个,大部分情况下是够用了。

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

那么,glEnableVertexAttribArray应该在glVertexAttribPointer之前还是之后调用?答案是都可以,只要在绘图调用(glDraw*系列函数)前调用即可。

不用glEnableVertexAttribArray对应属性时绘制内容为清除缓冲区颜色。在取消glEnableVertexAttribArray(0);注释后我的代码就可以得到正常的绘制结果。

部分内容来自:简书-熊皮皮
链接:http://www.jianshu.com/p/b05884a0ff8e
learnopengl.com以及learnopengl-cn.github.io

<think>好的,我需要解释这两个OpenGL接口的作用:glVertexAttribPointer和glEnableVertexAttribArray。首先,我得回忆一下顶点缓冲对象(VBO)和顶点数组对象(VAO)的相关知识。 用户给出的代码中,glVertexAttribPointer的第一个参数是0,说明是设置索引为0的顶点属性。第二个参数3,可能代表每个顶点的分量数,比如位置坐标有x、y、z三个分量。GL_FLOAT是数据类型,说明数据是浮点数。GL_FALSE表示不需要归一化。接下来的两个0分别是步长和偏移量,可能意味着数据是紧密排列的,没有间隔,从缓冲区的起始位置开始。 接下来,glEnableVertexAttribArray(0)的作用是启用索引为0的顶点属性数组。如果不启用的话,设置的属性指针可能不会被使用,导致渲染时没有顶点数据。 需要确认步长为0时,OpenGL是否会自动计算步长。根据OpenGL规范,当步长设为0时,会认为数据是紧密排列的,即每个属性数据之间的间隔等于数据类型大小乘以分量数。比如这里3个GLfloat,每个占4字节,所以步长应该是12字节,但用户代码中直接写0,这是正确的。 另外,需要说明这两个函数通常和VBO、VAO一起使用的情况。在绑定VBO后调用glVertexAttribPointer,这样顶点属性指针会关联到当前绑定的VBO。而glEnableVertexAttribArray则是启用对应的属性位置,这样在绘制时,比如glDrawArrays,就会从VBO中读取数据。 可能需要提到顶点着色器中location的对应关系,比如在着色器中用layout(location=0)来匹配这里的索引0,确保数据正确传递到着色器。 还要注意,旧版OpenGL可能需要在启用顶点属性数组前绑定VAO,但如果是核心模式,VAO是必须的。不过用户的问题没有提到VAO,可能只是基础解释,所以暂时可以不深入讨论VAO,除非有必要。 总结步骤:先解释每个参数的意义,再说明两个函数的作用,最后说明它们如何配合使用来传递顶点数据到着色器。</think>这两个接口是OpenGL中用于配置顶点属性数据的核心函数,主要用于将顶点数据传递给着色器。以下是逐步解释: --- ### 1. `glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)` #### 作用:定义顶点属性数据的格式和来源。 - **参数解析**: - **索引 `0`**:指定顶点着色器中属性变量(如 `layout(location=0) in vec3 position;`)的位置索引。此处对应着色器的 `location=0`。 - **分量数 `3`**:每个顶点由3个分量组成(例如3D坐标 `(x, y, z)`)。 - **数据类型 `GL_FLOAT`**:分量是浮点数(`GLfloat`)。 - **是否归一化 `GL_FALSE`**:数据不需要被归一化到 `[0,1]` 或 `[-1,1]`。 - **步长 `0`**:数据在内存中是连续紧密排列的,无间隔(自动计算为 `3 * sizeof(float)`)。 - **偏移量 `0`**:数据从缓冲对象的起始位置开始读取。 #### 底层原理: - 此函数将当前绑定的顶点缓冲对象(VBO)中的数据与着色器的属性位置关联。数据最终通过VBO传递给GPU。 --- ### 2. `glEnableVertexAttribArray(0)` #### 作用:启用指定索引的顶点属性数组。 - **参数 `0`**:启用着色器中 `location=0` 的属性数组。 - **必要性**:如果未启用,OpenGL将不会使用该位置的顶点数据,可能导致渲染错误(如黑屏)。 --- ### 3. 组合使用示例 ```cpp // 绑定VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 配置顶点属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); ``` - **效果**:顶点数据(如3D坐标)会通过 `location=0` 传递给顶点着色器。 --- ### 4. 顶点着色器对应代码 ```glsl #version 330 core layout(location = 0) in vec3 position; // 对应glVertexAttribPointer的索引0 void main() { gl_Position = vec4(position, 1.0); } ``` --- ### 总结 - `glVertexAttribPointer`:定义数据如何从VBO中读取。 - `glEnableVertexAttribArray`:激活对应的属性通道。 - 二者共同作用:将CPU端的顶点数据传输到GPU,供着色器处理。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值