按照现代标准,呈现多边形网格的首选方法似乎涉及将Vertex Buffer Objects与索引缓冲区结合使用(最终由对glDrawElements()
的调用绘制),这正是我试图将这些东西包裹起来的原因概念。另外,我坚持使用glVertexAttribPointer()
代替deprecated glVertexPointer()
,glNormalPointer()
等。
我使用的是自定义二进制3d文件格式(Wavefront .OBJ派生文件),其内容可以或多或少直接memcpy()
到顶点数组。这是我声明我的vertex
结构的方式:
typedef struct vertex_ {
float vx,vy,vz;
float nx,ny,nz;
float padding[2]; // align to 32 bytes
} vertex;
loadBObj()
函数返回索引缓冲区(实现为unsigned short int
的简单数组),并用关联的顶点/法线数据填充顶点数组(使用的所有模型都已导出为具有逐顶点法线的以获得更平滑的阴影效果)。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处理过程中发生了什么有趣的事情吗?
最佳答案
您在使用着色器吗?您只应将glVertexAttribPointer与着色器一起使用,并且必须明确告诉它哪个attrib数组与哪个输入变量一起使用。 (glGetAttribLocation / glBindAttribLocation)。
如果您使用的是固定管线,则必须坚持使用glVertexPointer / glNormalPointer。
关于c++ - glVertexAttribPointer故障(OpenGL 3.x前向兼容上下文),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9539409/