0

按照现代标准,渲染多边形网格的首选方法似乎涉及使用顶点缓冲区对象和索引缓冲区(最终通过调用来绘制glDrawElements()),这正是我试图围绕这些概念进行思考的原因。另外,我坚持使用glVertexAttribPointer()而不是弃用 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 数组),并用相关的顶点/法线数据填充顶点数组(所有使用的模型都已导出为具有每个顶点法线以获得更平滑的着色结果) .

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

  • 这是由上述程序生成的:

img2

我的 VBO 处理中发生了什么有趣的事情吗?

4

3 回答 3

2

看来您的法线没有正确通过

这可能是由于您应该拥有

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

由于您同时指定了 0 和 1 指针。(目前你只有第一行)

于 2012-03-02T19:49:45.303 回答
1

你在使用着色器吗?您只应该将 glVertexAttribPointer 与着色器一起使用,并且您必须明确告诉它哪个属性数组与哪个输入变量一起使用。(glGetAttribLocation/glBindAttribLocation)。

如果您使用的是固定管道,则必须坚持使用 glVertexPointer/glNormalPointer。

于 2012-03-02T23:30:36.703 回答
0

我认为这里可能发生的是三角形*颠倒了。您可以通过将每个第一个顶点与每个第三个顶点交换来进行测试。

  • 由于您使用的是四边形,这显然不是错误。但是您可以尝试每秒与每个第三个顶点交换。
于 2012-03-02T19:54:05.020 回答