C++ VBO 渲染问题

Posted

技术标签:

【中文标题】C++ VBO 渲染问题【英文标题】:C++ VBO rendering issue 【发布时间】:2016-04-22 01:11:46 【问题描述】:

这段代码工作正常,呈现正确(没有发布所有相关代码,因为我认为这些部分有问题):

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

...初始化:

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);

有人可以解释我在这里做错了什么吗?为什么第一个代码有效,而最后一个代码无效?

【问题讨论】:

由 beps 编写,由 kebs 编辑 【参考方案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

【讨论】:

【参考方案2】:

我相信你原来的渲染是正确的,因为顶点恰好落在相关的坐标上。我认为问题在于您的步幅和初始位置。

因为你的数组看起来像

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 .

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

【讨论】:

我试过了,但仍然渲染不正确:link 可能其他地方有问题 @beps 可能是它在缓冲区外渲染垃圾数据。您的 glDrawArrays 调用应该渲染顶点数,而不是浮点数。 (尝试将其更改为 verts[num].size() / 5)您能否提供一个链接说明它的外观? size() / 5 现在看起来像这样 link ,它应该是这样的,xy 0,0 在左上角 link 用原始代码渲染 我正在尝试添加 Z 值,以便我可以将深度与其他渲染内容一起使用,将它们放在 VBO 渲染数据的后面或前面。这是我的 glOrtho,但我认为这不会影响渲染 glOrtho(0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, -1.0f, 16777215.0f); 请注意,白色纹理是纹理文件的一部分,我在纹理文件中将其更改为绿色,上面带有混乱渲染的图像链接是绿色而不是白色,它是第一个平铺纹理偏移量 0,0 处的文件

以上是关于C++ VBO 渲染问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 VBO 渲染顶点的问题 - OpenGL

OpenGL 使用单个 VBO 渲染多个对象,并使用另一个 VBO 更新对象的矩阵

OpenGL - 会使用多个 VBO 减慢渲染速度吗?

渲染一个包含两个 VBO 的 VAO

使用 JOGL 使用 VBO 渲染随机引发异常

Android OpenGL ES 2. 0 VBO 不渲染