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 渲染问题的主要内容,如果未能解决你的问题,请参考以下文章