C ++ VBO渲染问题

时间:2016-04-22 01:11:46

标签: c++ opengl vbo

这段代码的工作方式与它应该有效,渲染正确(没有发布每一段相关代码,因为我认为这些部分有问题):

std::vector<GLuint> vboId;
std::vector< std::vector<GLfloat> > verts;

... INIT:

verts[num].push_back(x);
verts[num].push_back(y);
//verts[num].push_back(0);
// texture offset
verts[num].push_back(0);
verts[num].push_back(offset);

verts[num].push_back(x + TILE_SIZE);
verts[num].push_back(y);
//verts[num].push_back(0);
// texture offset
verts[num].push_back(1);
verts[num].push_back(offset);

verts[num].push_back(x + TILE_SIZE);
verts[num].push_back(y + TILE_SIZE);
//verts[num].push_back(0);
// texture offset
verts[num].push_back(1);
verts[num].push_back(offset + zsize);

verts[num].push_back(x);
verts[num].push_back(y + TILE_SIZE);
//verts[num].push_back(0);
// texture offset
verts[num].push_back(0);
verts[num].push_back(offset + zsize);
...
glBindBuffer(GL_ARRAY_BUFFER, vboId[num]);
glBufferData(GL_ARRAY_BUFFER, verts[num].size() * sizeof(GLfloat), verts[num].data(), GL_STATIC_DRAW);

...渲染:

glBindBuffer(GL_ARRAY_BUFFER,vboId[num]);

glTexCoordPointer(2,GL_FLOAT,sizeof(verts[num]),(void*)(sizeof(GLfloat)*2));
glVertexPointer(2,GL_FLOAT,sizeof(verts[num]),0);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);

glDrawArrays(GL_QUADS, 0, verts[num].size());

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

但是当我尝试通过修改代码来添加Z值时,所有内容都会混乱:

...初始化

verts[num].push_back(x);
verts[num].push_back(y);
verts[num].push_back(0);
// texture offset
verts[num].push_back(0);
verts[num].push_back(offset);

verts[num].push_back(x + TILE_SIZE);
verts[num].push_back(y);
verts[num].push_back(0);
// texture offset
verts[num].push_back(1);
verts[num].push_back(offset);

verts[num].push_back(x + TILE_SIZE);
verts[num].push_back(y + TILE_SIZE);
verts[num].push_back(0);
// texture offset
verts[num].push_back(1);
verts[num].push_back(offset + zsize);

verts[num].push_back(x);
verts[num].push_back(y + TILE_SIZE);
verts[num].push_back(0);
// texture offset
verts[num].push_back(0);
verts[num].push_back(offset + zsize);
...
glBindBuffer(GL_ARRAY_BUFFER, vboId[num]);
glBufferData(GL_ARRAY_BUFFER, verts[num].size() * sizeof(GLfloat), verts[num].data(), GL_STATIC_DRAW);

...渲染:

glBindBuffer(GL_ARRAY_BUFFER,vboId[num]);

glTexCoordPointer(2,GL_FLOAT,sizeof(verts[num]),(void*)(sizeof(GLfloat)*3));
glVertexPointer(3,GL_FLOAT,sizeof(verts[num]),0);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);

glDrawArrays(GL_QUADS, 0, verts[num].size());

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

有人可以解释我在这里做错了吗?为什么第一个代码可以工作,但最后一个代码不工作?

2 个答案:

答案 0 :(得分:1)

我想我已经解决了..这段代码使它像它应该的那样:

glTexCoordPointer(2,GL_FLOAT,sizeof(GLfloat) * 5,(void*)(sizeof(GLfloat) * 3));
glVertexPointer(3,GL_FLOAT,sizeof(GLfloat) * 5,(void*)0);
...
glDrawArrays(GL_QUADS, 0, verts[num].size() / 5);

但是我不确定它是否真的正确,我没有看到任何文物但却不知道幕后发生了什么...... 感谢您的帮助,如果有人能确认代码是否正确,请执行

但我在这里理解的是glTexCoordPointer(* 5,* 3)从第三个数组索引(第一个纹理坐标)开始,每次向前增加5个(索引* 5)个元素。 glVertexPointer(* 5,0)从数组索引0开始,每次增加5。 因此:

verts[num].push_back(x); // index 0
verts[num].push_back(y); // index 1
verts[num].push_back(0); // index 2
// texture offset
verts[num].push_back(0); // index 3
verts[num].push_back(offset); // index 4

我可以回过头来添加更多东西...... http://i.imgur.com/Iemih6d.png

答案 1 :(得分:0)

我相信你的原始版本只能正确渲染,因为顶点碰巧落在相关的坐标上。我认为问题在于您的步伐和初始位置。

因为您的数组看起来像

X-Y-Z-U-V

顶点也会有步幅,因为它们必须跳两个浮点才能到达下一个坐标。纹理坐标也将具有初始指针位置。

glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 3, sizeof(GLfloat) * 3);
glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 2, 0);

这就是说,对于纹理,从索引3(u)开始,读取两个元素(u和v),然后向前移动三个元素,这将是下一个u,因为它跳过x,y和z

对于verticies,从0(x)开始,读取三个元素x,y和z,然后跳过两个从下一个x开始。