glVertexAttribPointer麻烦(OpenGL 3.x前向兼容上下文)

时间:2012-03-02 19:44:33

标签: c++ opengl opengl-3

按照现代标准,渲染多边形网格的首选方法似乎涉及将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 s的简单数组),并使用关联的顶点/普通数据填充顶点数组(所有使用的模型都已导出为 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

  • 这是由上述程序制作的:

img2 http://i43.tinypic.com/sgmhhi.png

我的VBO处理中是否有一些有趣的东西?

3 个答案:

答案 0 :(得分:2)

您的法线似乎没有正确传递

这可能是因为你应该

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

因为您指定了0和1指针。 (目前你只有第一行)

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

我认为这里可能发生的是三角形*是相反的。您可以通过每个第一个顶点交换每个第三个顶点来测试它。

  • 既然你正在使用四边形,那显然不是错误。但是你可以尝试用每个第三个顶点交换每秒。