You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL中glVertexAttribPointer的stride参数含义及用法疑问

关于glVertexAttribPointer中stride参数的困惑

我刚学OpenGL,想搞懂每一行代码的作用,但卡在了glVertexAttribPointer的stride参数上。文档说:

指定连续通用顶点属性之间的字节偏移量。如果stride为0,则认为通用顶点属性在数组中紧密排列。初始值为0。

我能理解stride为0的场景:比如顶点数组只有紧密排列的位置属性时:

GLfloat vertices[] = {
  //x,     y,     z
    0.0f,  0.5f,  0.0f,  // 顶部中点
   -0.5f, -0.5f,  0.0f,  // 左下角
    0.5f, -0.5f,  0.0f   // 右下角
};

这时设置stride为0没问题:

glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);

但给顶点数组加上颜色属性后:

GLfloat vertices[] = {
  //x,     y,     z,     r,     g,     b
    0.0f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  // 顶部中点
   -0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  // 左下角
    0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f   // 右下角
};

这时必须把stride设为每个顶点的总字节数(也就是6*sizeof(GLfloat))才能正常运行,我搞不懂为什么。如果按自己的逻辑把stride设为3*sizeof(GLfloat)(以为是两个位置属性之间的间隔),就会出问题。


核心误区:stride是"下一个顶点同属性的起始偏移",不是"同属性元素的间隔"

你之前的错误在于误解了stride的定义——它不是指同一个属性的两个值之间的间隔,而是指从当前顶点的这个属性的第一个字节,到下一个顶点的同一个属性的第一个字节,中间隔了多少字节。

拿带颜色的顶点数组举例:

  • 第一个顶点的位置属性从索引0开始,占3个float(12字节);
  • 接下来是它的颜色属性,占3个float(12字节);
  • 第二个顶点的位置属性,是从第一个顶点位置的起始字节往后数6*sizeof(GLfloat)(24字节)的位置开始的——因为每个顶点总共占6个float的空间。

如果把stride设为3*sizeof(GLfloat)(12字节),OpenGL会认为:

  • 第一个位置在0字节,第二个位置就在0+12字节的位置(也就是第一个顶点的r值),第三个位置在12+12=24字节的位置(第二个顶点的r值),这完全不是你要的位置数据,自然会出问题。

换个更直白的说法:
当你调用glVertexAttribPointer时,你是在告诉OpenGL:

  1. 这个属性每一组数据占3个GL_FLOAT;
  2. 从buffer的某个偏移量(最后一个参数)开始取第一组数据;
  3. 要取下一组数据时,直接往前跳stride个字节就行。
  • 单属性紧密排列时,下一组位置数据就在当前组的结尾,所以stride设为0(OpenGL会自动计算成3*sizeof(GLfloat));
  • 多属性交叉排列时,下一组位置数据要跳过当前顶点的所有其他属性(这里就是颜色的3个float),所以总跨度是整个顶点的大小:3+3个float的字节数,也就是6*sizeof(GLfloat)。

内容的提问来源于stack exchange,提问作者octopus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:01:30