按照现代标准,渲染多边形网格的首选方法似乎涉及使用 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 int
数组),并填充具有相关顶点/法线数据的顶点数组(所有使用的模型都已导出以具有 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 处理过程中发生了什么有趣的事情吗?
最佳答案
看来你的法线没有正确通过
这可能是因为你应该有
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
因为您同时指定了 0 和 1 指针。 (目前你只有第一行)
关于c++ - glVertexAttribPointer 问题(OpenGL 3.x 向前兼容上下文),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9539409/