- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在正确指向顶点数组时遇到问题:
const float vertices[] = {
/* position */ 0.75f, 0.75f, 0.0f, 1.0f, /* color */ 1.0f, 0.0f, 0.0f, 1.0f,
/* position */ 0.75f, -0.75f, 0.0f, 1.0f, /* color */ 0.0f, 1.0f, 0.0f, 1.0f,
/* position */ -0.75f, -0.75f, 0.0f, 1.0f, /* color */ 0.0f, 0.0f, 1.0f, 1.0f, };
...
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)16);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
我不明白步幅和偏移量是如何工作的。在我的情况下使用 glVertexAttribPointer()
的正确方法是什么?
最佳答案
由于glVertexAttribPointer经常造成麻烦,我尝试在这里进一步解释一下。
属性数组中第i个属性的起始位置计算公式为:
startPos(i) = offset + i * stride
(来自 derhass' another answer)
如果您需要代码示例,请继续阅读。
来自Formatting VBO Data ,我们知道我们可以用三种格式管理顶点数据。以绘制三角形为例,顶点颜色和纹理颜色混合,准备顶点属性数据的方法如下:
<小时/>#way1 每个属性一个VBO。
这种格式类似于:(xyzxyz...)(rgbrgb...)(stst...),我们可以让 sride = 0 和 offset = 0。
void prepareVertData_moreVBO(GLuint& VAOId, std::vector<GLuint>& VBOIdVec)
{
// positon
GLfloat vertPos[] = {
-0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f,
};
// color
GLfloat vertColor[] = {
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
};
// texture coordinate
GLfloat vertTextCoord[] = {
0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f
};
GLuint VBOId[3];
glGenVertexArrays(1, &VAOId);
glBindVertexArray(VAOId);
glGenBuffers(3, VBOId);
// specify position attribute
glBindBuffer(GL_ARRAY_BUFFER, VBOId[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertPos), vertPos, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// specify color attribute
glBindBuffer(GL_ARRAY_BUFFER, VBOId[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertColor), vertColor, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
// specify texture coordinate attribute
glBindBuffer(GL_ARRAY_BUFFER, VBOId[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertTextCoord), vertTextCoord, GL_STATIC_DRAW);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
VBOIdVec.push_back(VBOId[0]);
VBOIdVec.push_back(VBOId[1]);
VBOIdVec.push_back(VBOId[2]);
}
<小时/>
#way2:每个属性都是连续的,在单个 VBO 中批量处理。
这种格式就像:(xyzxyzxyz... rgbrgb... ststst...),我们可以让stride=0,但要指定偏移量。
void prepareVertData_seqBatchVBO(GLuint& VAOId, std::vector<GLuint>& VBOIdVec)
{
GLfloat vertices[] = {
-0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, // position
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // color
0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f // texture coordinate
};
GLuint VBOId;
glGenVertexArrays(1, &VAOId);
glBindVertexArray(VAOId);
glGenBuffers(1, &VBOId);
glBindBuffer(GL_ARRAY_BUFFER, VBOId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// specifiy position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); // stride can aslo be 3 * sizeof(GLfloat)
glEnableVertexAttribArray(0);
// specify color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(9 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// specify texture coordinate
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(18 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
VBOIdVec.push_back(VBOId);
}
<小时/>
#way3:单个 VBO 中的交错属性
这种格式就像:(xyzrgbstxyzrgbst...),我们必须手动指定偏移量和步幅。
void prepareVertData_interleavedBatchVBO(GLuint& VAOId, std::vector<GLuint>& VBOIdVec)
{
// interleaved data
GLfloat vertices[] = {
-0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 0
0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 1
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // 2
};
GLuint VBOId;
glGenVertexArrays(1, &VAOId);
glBindVertexArray(VAOId);
glGenBuffers(1, &VBOId);
glBindBuffer(GL_ARRAY_BUFFER, VBOId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// specify position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// specify color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
8 * sizeof(GLfloat),(GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// specify texture coordinate
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,
8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
VBOIdVec.push_back(VBOId);
}
感谢 derhass 的回答。
关于OpenGL 3/4 glVertexAttribPointer 步长和偏移计算错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16380005/
根据我的理解,OpenGL 在将所有顶点属性数据用于顶点着色器之前将其转换为 32 位 float 。但是 glVertexAttribPointer 也采用数据类型 GL_BYTE 和 GL_UNS
我来这里是为了消除专家对 opengl 的一些困惑。感谢您的帮助! private int vbo; private int ibo; vbo = glGenBuffers(); ibo = glGe
private int vbo; private int ibo; vbo = glGenBuffers(); ibo = glGenBuffers(); glBindBuffer(GL_ARRAY_
我正在编写一个 glsl 1.3+ 查看器,我需要经常更改着色器的源而不是删除然后重新创建...... 但是,opengl 的手册中没有给出一些关于重新定义顶点属性布局的信息。 上一次调用会发生什么
glVertexAttribPointer 函数的 stride 参数如何工作?假设我有一个 64 字节大的缓冲区。我想存储 2 个顶点,每个顶点大小为 32 字节。如果顶点依次开始,stride参数
当 glVertexAttribPointer 时,从文档中并不明显。应该调用。看起来它是 VBO 初始化的一部分,但我注意到在渲染过程中调用它的示例代码。 glVertexAttribPointer
只是想确保我正确理解这一点(我会在 SO Chat 上问,但它已经死在那里了!): 我们有一个顶点数组,我们通过绑定(bind)它使其成为“当前” 然后我们有一个缓冲区,我们将其绑定(bind)到目标
glVertexAttribPointer() 的第一个参数是表示顶点属性所在位置的索引,Opengl 至少提供 16 个槽。 我希望所有 16 个都代表不同的顶点属性(position=0、uvs=
当我使用 glVertexAttribPointer 时,OpenGL 如何知道我指的是顶点、法线还是颜色?这是我的一段代码: glEnableVertexAttribArray(0); glVert
我对如何在不同的多个程序之间正确切换感到困惑。我已将问题缩小到以下范围:如果我使用 NO_HDR 运行,它工作正常;我得到一些线条、一艘 spaceship 和一些球体,并按此顺序渲染。如果我使用 H
所以我有这门课: class BRENDERDLL_API Vertex { private: glm::vec3 pos; public: Vertex(glm::vec3 pos)
我看过其他人的代码,他们在初始化 vao 时只调用了 glVertexAttribPointer()。当我这样做时,只有我场景中的第一个对象被渲染,但如果我调用它每一帧 * 每个对象,一切都渲染得很好
我正在关注 Ray Wenderlich OpenGL ES 2 tutorial for the iPhone. 我对他对 glVertexAttribPointer 的用法感到困惑并希望有人能解释
有 glVertexAttribPointer() glVertexAttribIPointer() glVertexAttribLPointer() 据我所知,glVertexAttribPoint
我已将错误范围缩小到此 OpenGL 调用: glVertexAttribPointer(var.vertex, 4, GL_FLOAT, GL_FALSE, 0, 0); 前面没有错误,后面有 GL
我有 OpenGL 代码,对所有模型数据使用一个 VAO,并使用两个 VBO。第一个用于标准顶点属性,例如位置和法线,第二个用于模型矩阵。我正在使用实例化绘制,因此我将模型矩阵加载为实例化数组(基本上
因此,在为我正在处理的 3D 场景编写模型加载器的过程中,我决定像这样打包顶点、纹理和法线数据: VVVVTTTNNN 对于每个顶点,其中 V = 顶点坐标,T = UV 坐标,N = 法线坐标。当我
我正在通读并尝试学习着色器,但我突然对将信息传递到着色器感到困惑。 glVertexAttrib 和 glVertexAttribPointer 有什么区别?有不同的时间使用它们吗?它们只是做同一件事
GLSL 代码和传递数据的 native 代码之间的类型必须匹配到什么程度? 例如,假设我有着色器代码: uniform float uFloat; uniform int uInt; in floa
我正在尝试使用单个 VBO 和着色器以不同颜色渲染 3 个点。我将位置和颜色值传递给单个 VBO: vertices = np.array([[0, 0.1, 0.6, 1, 1, 0], [0.3,
我是一名优秀的程序员,十分优秀!