OpenGL 3/4 glVertexAttribPointer跨度和偏移量计算错误 [英] OpenGL 3/4 glVertexAttribPointer stride and offset miscalculation
问题描述
我无法正确指向我的顶点数组:
I am having a problem getting my vertex array pointed to properly:
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()
的正确方法是什么?
I do not understand how stride and offset work.
What is the correct way of going about using glVertexAttribPointer()
in my situation?
推荐答案
由于glVertexAttribPointer经常会引起麻烦,因此我尝试在此处进一步说明.
Since glVertexAttribPointer often make troubles, I try to further explain it here.
在属性数组中计算第i个属性的起始位置的公式为:
The formula to calculate the start pos of the i-th attribute in attributes array is :
startPos(i) = offset + i * stride
(摘自解开另一个答案)
并在下图中说明:
如果您需要代码示例,请继续阅读.
通过格式化VBO数据,我们知道可以以三种格式管理顶点数据.举一个绘制三角形的示例,该三角形将vert颜色和纹理颜色混合在一起,这是准备vert属性数据的方法:
From Formatting VBO Data, we know we can manage our vertex data in three format. Make a example of drawing a triangle , with vert color and texture color mixed, here is the way to prepare vert attribute data:
#way1每个属性都有一个VBO.
这种格式如下:(xyzxyz ...)(rgbrgb ...)(stst ....),我们可以让sride = 0和offset = 0.
this format like : (xyzxyz...)(rgbrgb...)(stst....), and we can let both sride = 0 and 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]);
}
#way2:每个属性是连续的,并在单个VBO中进行批处理.
这种格式类似于:(xyzxyzxyz ... rgbrgb ... ststst ...),我们可以让stride = 0但应指定偏移量.
this format is like: (xyzxyzxyz... rgbrgb... ststst...), we can let stride=0 but offset should be specified.
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);
}
#way3:单个VBO中的交错属性
此格式类似于:(xyzrgbstxyzrgbst ...),我们必须手动指定偏移量和步幅.
this format is like: (xyzrgbstxyzrgbst...),we have to manually specify the offset and stride .
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);
}
感谢derhass的回答.
And thanks for derhass's answer.
这篇关于OpenGL 3/4 glVertexAttribPointer跨度和偏移量计算错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!