【发布时间】:2012-03-02 19:44:32
【问题描述】:
按照现代标准,渲染多边形网格的首选方式似乎涉及使用Vertex Buffer Objects 和索引缓冲区(最终通过调用glDrawElements()),这正是我试图包装我的围绕这些概念。另外,我坚持使用glVertexAttribPointer() 而不是deprecated glVertexPointer()、glNormalPointer() 等。
我正在使用自定义的二进制 3d 文件格式(Wavefront .OBJ 衍生文件),其内容可以或多或少直接memcpy()'d 到顶点数组。以下是我声明 vertex 结构的方式:
typedef struct vertex_ {
float vx,vy,vz;
float nx,ny,nz;
float padding[2]; // align to 32 bytes
} vertex;
loadBObj() 函数返回一个索引缓冲区(实现为unsigned short ints 的简单数组),并用相关的顶点/法线数据填充顶点数组(模型使用所有已导出为具有 per-vertex-normals 以获得更平滑的着色结果)。
indices = loadBObj("pharaoh.bobj", false, &VBOid);
加载代码本身经过验证可以正常工作。
现在,loadBObj() 中正在做的事情是正在创建一个新的 VBO,如下所示:
glGenBuffers(1, VBOid);
glBindBuffer(GL_ARRAY_BUFFER, *VBOid);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)*vcount, &vertarray[0].vx, GL_STATIC_DRAW);
在loadBObj() 被调用后,一个索引缓冲区对象(可能不应该这样称呼)被创建如下:
glGenBuffers(1, &IBOid);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short int)*qfcount*4, indices, GL_STATIC_DRAW);
好的。在实际渲染网格时,我使用了以下代码:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
...
glBindBuffer(GL_ARRAY_BUFFER, VBOid);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(0));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(3*sizeof(float)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
glDrawElements(GL_QUADS, qfcount*4, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
这会产生绝对正确的几何图形,但阴影不太正确:
- 这是模型的图像,以立即模式呈现:
img http://i44.tinypic.com/i36zcg.png
- 这是由上述程序生成的:
我的 VBO 处理过程中发生了什么有趣的事情吗?
【问题讨论】:
-
在 gDEBugger 或类似的东西下运行它,并验证 VBO 中的所有数据是否正确。如果是,是时候检查着色器了。此外,
GL_QUADS已被弃用并从核心配置文件中消失。 -
@CatPlusPlus:好的,我现在已经彻底检查了 VBO 的内容(gDEBugger = fantabulous 实用程序顺便说一句,干杯),看起来没问题。现在,“检查着色器”到底是什么意思?