use*_*858 12 opengl attributes offset vertex stride
我的顶点数组指向正确时遇到问题:
Run Code Online (Sandbox Code Playgroud)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()在我的情况下使用的正确方法是什么?
小智 31
由于glVertexAttribPointer经常会遇到麻烦,我试着在这里进一步解释.
计算属性数组中第i个属性的起始位置的公式为:
startPos(i) = offset + i * stride(来自derhass'的另一个答案)
如果您需要代码示例,请继续阅读.
从格式化VBO数据,我们知道我们可以用三种格式管理顶点数据.举一个绘制三角形的例子,混合了vert颜色和纹理颜色,这里是准备vert属性数据的方法:
#way1每个属性都是一个VBO.
这种格式如:(xyzxyz ...)(rgbrgb ...)(stst ....),我们可以让sride = 0和offset = 0.
void prepareVertData_moreVBO(GLuint& VAOId, std::vector<GLuint>& VBOIdVec)
{
GLfloat vertPos[] = {
-0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, // positon
};
GLfloat vertColor[] = {
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // color
};
GLfloat vertTextCoord[] = {
0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f // texture coordinate
};
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]);
}
Run Code Online (Sandbox Code Playgroud)
#way2:每个属性都是顺序的,在一个VBO中进行批处理.
这种格式如:(xyzxyzxyz ... rgbrgb ... ststst ...),我们可以让stride = 0但是应该指定offset.
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(GL_FLOAT)
glEnableVertexAttribArray(0);
// specify color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(9 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(1);
// specify texture coordinate
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(18 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
VBOIdVec.push_back(VBOId);
}
Run Code Online (Sandbox Code Playgroud)
#way3:单个VBO中的Interleaved属性
这种格式如:(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(GL_FLOAT), (GLvoid*)0);
glEnableVertexAttribArray(0);
// specify color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
8 * sizeof(GL_FLOAT),(GLvoid*)(3 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(1);
// specify texture coordinate
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,
8 * sizeof(GL_FLOAT), (GLvoid*)(6 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
VBOIdVec.push_back(VBOId);
}
Run Code Online (Sandbox Code Playgroud)
并感谢derhass的回答.
der*_*ass 22
步长和偏移量以字节为单位指定.您正在使用具有位置和颜色的交错顶点数组作为4个浮点数.要从特定属性数组中的第i个元素到下一个元素,距离为8个浮点数,因此步长应为8*sizeof(GLfloat).偏移量是缓冲区中每个属性数组的第一个元素的字节位置,因此在您的示例中,位置为0,而对于颜色,它是4*sizeof(GLfloat)