我在使用openGL显示所有对象时遇到问题。我有5个不同的obj文件:多维数据集,茶壶,灯,一个人和一辆汽车。立方体,灯和人画得很好,但是茶壶和汽车不能正确渲染。
我有一个读取obj文件的方法,并且我已经进行了打印输出,以仔细检查输出是否与obj文件匹配,并且它们都是正确的。
这是我的draw()代码,我认为问题出在这里
glBegin(GL_TRIANGLES);
for(int i = 0; i < f_count; i++){
if(f[i].type == 'c'){
GLfloat * color = new GLfloat[4];
color[0] = f[i].x;
color[1] = f[i].y;
color[2] = f[i].z;
color[3] = 1;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
}
else{
glVertex3f(vn[(f[i].vn1-1)].x, vn[(f[i].vn1-1)].y, vn[(f[i].vn1-1)].z); // normals
glVertex3f(vn[(f[i].vn2-1)].x, vn[(f[i].vn2-1)].y, vn[(f[i].vn2-1)].z); // normals
glVertex3f(vn[(f[i].vn3-1)].x, vn[(f[i].vn3-1)].y, vn[(f[i].vn3-1)].z); // normals
glVertex3f(v[(f[i].v1-1)].x, v[(f[i].v1-1)].y, v[(f[i].v1-1)].z);
glVertex3f(v[(f[i].v2-1)].x, v[(f[i].v2-1)].y, v[(f[i].v2-1)].z);
glVertex3f(v[(f[i].v3-1)].x, v[(f[i].v3-1)].y, v[(f[i].v3-1)].z);
}
}
glEnd();
前三个是法线,其他三个是顶点
这是我的头文件和结构
struct NormalVector
{
GLfloat x, y, z;
};
struct Vertex
{
GLfloat x, y, z, w;
};
struct Faces
{
int v1,v2,v3, vn1,vn2,vn3;
char type;
GLfloat x,y,z;
};
我不确定我做错了什么,或者我对所提供的代码做错了什么。.但这是我“觉得”错误所在的地方。
说明:
顶点* v是顶点指针
VectorNormal * vn是法线向量指针
人脸* f是人脸指针
在draw()方法中,它循环遍历f struct指针并检查类型,如果它是颜色类型,则添加glMaterialfv(..,..,..);如果不是,则它将获取面的索引值,并将其通过“顶点”结构指针和“矢量法线”结构指针。
这是我的茶壶
这是它应该看起来像的茶壶
最佳答案
您通过glNormal()
而不是glVertex()
提供法线。
同样,glNormal()
仅锁存某些状态。在下一次glVertex()
调用之前,什么都没有真正发送到OpenGL,此时,锁存的颜色/正常/位置状态被捆绑并向下传递到管道中。
只有最新的glNormal()
调用才会生效,因为它将覆盖自上一个glNormal()
之后的任何其他glVertex()
。
因此,您需要插入glNormal()
调用:
glNormal3f(vn[(f[i].vn1-1)].x, vn[(f[i].vn1-1)].y, vn[(f[i].vn1-1)].z);
glVertex3f(v[(f[i].v1-1)].x, v[(f[i].v1-1)].y, v[(f[i].v1-1)].z);
glNormal3f(vn[(f[i].vn2-1)].x, vn[(f[i].vn2-1)].y, vn[(f[i].vn2-1)].z);
glVertex3f(v[(f[i].v2-1)].x, v[(f[i].v2-1)].y, v[(f[i].v2-1)].z);
glNormal3f(vn[(f[i].vn3-1)].x, vn[(f[i].vn3-1)].y, vn[(f[i].vn3-1)].z);
glVertex3f(v[(f[i].v3-1)].x, v[(f[i].v3-1)].y, v[(f[i].v3-1)].z);