更新
看起来我的法线工作正常,这与我画脸的方式有关(只画了一半),我不知道为什么——
如果您可以查看我之前的代码(如下所示)
原帖
我目前正在为 .obj 文件类型开发解析器/渲染器。我遇到了显示法线向量的问题:
没有法线:
使用法线:
出于某种原因,我无法弄清楚为什么只有一半的法线向量有效果,而另一半则表现得好像根本没有一张脸。
这是我在 obj 文件中加载的代码:
void ObjModel::Load(string filename){
ifstream file(filename.c_str());
if(!file) return;
stringstream ss;
string param, line;
float nparam, cur;
vector<vector<float> > coords;
vector<float> point;
while(getline(file, line)){
ss.clear();
ss.str(line);
ss >> param;
//vertex
if(param == "v"){
for(int i = 0; i < 3; i++){
ss >> nparam;
this->vertices.push_back(nparam);
}
}
//face
else if(param == "f"){
coords.clear();
point.clear();
for(int i = 0; i < 3; i++){
ss >> nparam;
nparam--;
for(int j = 0; j < 3; j++){
cur = this->vertices[nparam * 3 + j];
this->faces.push_back(cur);
point.push_back(cur);
}
coords.push_back(point);
}
point = this->ComputeNormal(coords[0], coords[1], coords[2]);
for(int i = 0; i < 3; i++) this->normals.push_back(point[i]);
}
else continue;
}
}
void ObjModel::Render(){
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, &this->faces[0]);
glNormalPointer(GL_FLOAT, 0, &this->normals[0]);
glDrawArrays(GL_TRIANGLES, 0, this->faces.size() / 3);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
这是计算法线向量的函数:
vector<float> ObjModel::ComputeNormal(vector<float> v1, vector<float> v2, vector<float> v3){
vector<float> vA, vB, vX;
float mag;
vA.push_back(v1[0] - v2[0]);
vA.push_back(v1[1] - v2[1]);
vA.push_back(v1[2] - v2[2]);
vB.push_back(v1[0] - v3[0]);
vB.push_back(v1[1] - v3[1]);
vB.push_back(v1[2] - v3[2]);
vX.push_back(vA[1] * vB[2] - vA[2] * vB[1]);
vX.push_back(vA[2] * vB[0] - vA[0] * vB[2]);
vX.push_back(vA[0] * vB[1] - vA[1] * vB[0]);
mag = sqrt(vX[0] * vX[0] + vX[1] * vX[1] + vX[2] * vX[2]);
for(int i = 0; i < 3; i++) vX[i] /= mag;
return vX;}
我已经检查过以确保有相同数量的法线向量和面(如果我是对的,应该有)。
先感谢您!:)
编辑这是我启用/禁用 OpenGL 功能的方式:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
GLfloat amb_light[] = 0.1, 0.1, 0.1, 1.0 ;
GLfloat diffuse[] = {0.6, 0.6, 0.6, 1};
GLfloat specular[] = {0.7, 0.7, 0.3, 1};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb_light);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
glLightModeli(L_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDisable(GL_CULL_FACE);