OpenGL使用glDrawArrays绘图时如何正确设置顶点颜色等属性
问题根源
你当前的代码存在两个核心问题:
- 你使用的是OpenGL 3.3核心模式,当前调用的
glEnableClientState、glVertexPointer属于已被核心模式废弃的固定管线API,无法适配自定义着色器的属性配置。 - 你只配置了位置属性的数据读取规则,完全没有给着色器中
location=1的颜色属性指定数据来源和读取规则,所以着色器拿不到对应的颜色值。
推荐解决方案(核心模式标准实现)
1. 初始化阶段(仅执行一次)创建VAO、VBO并配置属性指针
你需要提前把顶点数据上传到显存,并且把属性读取规则存储到VAO中,避免绘制时重复配置:
// 顶点数组(你原有定义不需要修改) GLfloat arr[] = { //position //color 300, 380, 0, 0, 1, 0, 300, 300, 0, 1, 1, 0, 380, 300, 0, 0, 1, 1, 380, 380, 0, 1, 0, 1 }; // 初始化阶段执行一次即可,不要放在绘制循环中 GLuint VAO, VBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(arr), arr, GL_STATIC_DRAW); // 配置位置属性(对应着色器location=0) // 参数:属性索引、分量数量、数据类型、是否归一化、步长(单顶点总字节数)、数据起始偏移 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0); glEnableVertexAttribArray(0); // 配置颜色属性(对应着色器location=1) // 颜色数据在每个顶点中偏移3个float的位置,所以偏移量为3*sizeof(GLfloat) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); // 解绑避免后续误修改 glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0);
2. 修改绘制阶段代码
替换原有旧API,直接绑定VAO即可完成绘制:
glPointSize(10); // 绑定已配置好属性的VAO glBindVertexArray(VAO); glDrawArrays(GL_POINTS, 0, 4); // 可选解绑 glBindVertexArray(0);
注:你的顶点着色器中位置属性定义为vec4,但你传入的是3维位置数据,glVertexAttribPointer会自动补全第四个分量为1.0,和你着色器中手动转vec4的逻辑匹配,无需修改着色器代码。
兼容模式替代方案(仅适用于非核心模式上下文)
如果你当前使用的是兼容模式OpenGL上下文,不想用VAO/VBO,可以直接修改原有绘制代码如下,不过该方案不推荐在3.3及以上版本使用:
glPointSize(10); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // 配置位置指针,步长为6个float,偏移为0 glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), arr); // 配置颜色指针,步长为6个float,偏移为3个float glColorPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), arr + 3); glDrawArrays(GL_POINTS, 0, 4); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
内容的提问来源于stack exchange,提问作者user15455820
相关产品推荐
相关产品推荐

