2012-05-25 52 views
1

目前的问题是我的3D对象只是部分渲染。如果我有一个典型的圆柱体,两端都是“填充的”,则两端完美呈现,而圆柱体本身不是。我有一个例子来说明。3D对象的部分渲染

这是代码是如何构建的:

struct ObjMeshVertex{ 
    Vector3f pos; 
    Vector2f texcoord; 
    Vector3f normal; 
}; 

struct ObjMeshFace{ 
    ObjMeshVertex vertices[3]; 
}; 

struct ObjMesh{ 
    std::vector<ObjMeshFace> faces; 
}; 

ObjMesh myMesh; 

for(size_t i = 0; i < faces.size(); ++i){ 
    ObjMeshFace face; 
    for(size_t j = 0; j < 3; ++j){ 
     face.vertices[j].pos  = positions[faces[i].pos_index[j] - 1]; 
     face.vertices[j].texcoord = texcoords[faces[i].tex_index[j] - 1]; 
     face.vertices[j].normal  = normals[faces[i].nor_index[j] - 1]; 
    } 
    myMesh.faces.push_back(face); 
} 

设置:

glGenVertexArraysOES(1, &_boxVAO); 
    glBindVertexArrayOES(_boxVAO); 

    int sizeOfFaces = myMesh.faces.size() * sizeof(ObjMeshFace); 
    glGenBuffers(1, &_boxBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, _boxBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeOfFaces, &(myMesh.faces[0]), GL_STATIC_DRAW); 


    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ObjMeshVertex), 0); 
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(ObjMeshVertex), (void*)offsetof(ObjMeshVertex, texcoord));   
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE ,sizeof(ObjMeshVertex), (void*)offsetof(ObjMeshVertex, normal)); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glEnableVertexAttribArray(2); 

    glBindVertexArrayOES(0); 

抽奖:

glBindVertexArrayOES(_boxVAO); 
glDrawArrays(GL_TRIANGLES, 0, indicesize); 

其中indicesize = myMesh.faces.size()

所以我的对象看起来像这样:

enter image description here

渲染结束这样的:

enter image description here

而且我只是在渲染1个对象,而不是多个,这似乎对这种行为有点古怪。

球并排侧:

enter image description here

最新渲染:

enter image description here

+0

它看起来像一个完整的子网缺失,这可能是导入器/解析器或obj导出器的错误。你能用更简单的模型(立方体?球体?)重现这一点吗?也许尝试在一个独立的OBJ查看器中验证模型(Assimp有一个独立的我相信)。 – Tim

+0

我从来没有成功地使用Assimp,但我只是试图渲染一个失败的球体。虽然如果我从我的分析器中的打印输出手动初始化我的索引和顶点,它呈现很好。我怀疑我的代码的一部分可能会出现问题,而我无法真正弄清楚。图像被附上。 – JavaCake

+2

你确定这个obj作家没有发出四边形吗?每个obj规范允许有超过3个顶点的面。你需要对它们进行三角测量。 – Tim

回答

1

(4,8 GL_TRIANGLES,0,indicesize);

其中indicesize = myMesh.faces.size()

而这就是问题所在。glDrawArrays的最后一个参数不是绘制图元的数量(在你的情况下是三角形),而是数组元素的数量(顶点),因此应该是3 * myMesh.faces.size()。所以目前你只绘制了三分之一的三角形。

+0

我需要更新我的代码。我已将其更改为'glDrawArrays(GL_TRIANGLES,0,7055);'7055与面的数量相同。而且,我现在可以在面包里闻到,应该是7055 * 3。该死的。 – JavaCake

+1

@JavaCake如果你有7055个面,那么它应该是'glDrawArrays(GL_TRIANGLES,0,21165)'。这是我答案的重点。 –

+0

非常好看。你让我今天一整天都感觉很好!如果你来到丹麦,可以随时光顾我的啤酒或十个:-) – JavaCake

2

通常可能有多种解释这个问题。

  1. 的OBJ装载机损坏或不考虑所有不同的OBJ功能,因此你放弃顶点的反弹/面临

  2. OBJ文件未尽管三角形的负载,在这种情况下, ,你通常不会松动整个“结构”,但你只注意到畸形的面孔。

  3. 你有一个剔除问题,因此,有些面孔是由你的调用绘制的,但不是由Opengl的面部剔除算法写在屏幕上。要排除此问题,请尝试使用glDisable语句禁用OpenGL中的Face Culling。它很容易测试。如果是这个问题,请注意不要在你的生产版本中禁用禁用选项,因为面部选择可以节省你的表演时间。

我希望这有助于

+0

我已附加到目前为止呈现的内容。我确定我的物体是三角形的。我已经检查过这些面并与顶点和法线进行比较,这看起来似乎没问题。 '3点'看起来很有趣,但是什么时候我必须禁用它? – JavaCake

+0

作为另一个我试图加载我的对象在一个数组'posX,posY,posZ,normX,normY,normZ'而不是我使用的主要方法。 – JavaCake

+0

正如你在渲染中看到的那样,平坦的表面渲染得很好。顶部呈现和“前”。 – JavaCake