声明:本文内容及源代码只能作为学习参考用,转载请注明本声明blog.csdn.net/t163ang。
搞图形学的童鞋经常需要用斯坦福三维模型来做实验的,模型ply文件下载地址:http://www.cc.gatech.edu/projects/large_models/index.html 及 http://graphics.stanford.edu/data/
因此需要将ply文件解析出来,并在opengl渲染,以下提供我的源代码:
void _normalize(const float* coord1,const float *coord2, const float *coord3,float *norm){
/* calculate Vector1 and Vector2 */
float va[3], vb[3], vr[3], val;
va[0] = coord1[0] - coord2[0];
va[1] = coord1[1] - coord2[1];
va[2] = coord1[2] - coord2[2];
vb[0] = coord1[0] - coord3[0];
vb[1] = coord1[1] - coord3[1];
vb[2] = coord1[2] - coord3[2];
/* cross product */
vr[0] = va[1] * vb[2] - vb[1] * va[2];
vr[1] = vb[0] * va[2] - va[0] * vb[2];
vr[2] = va[0] * vb[1] - vb[0] * va[1];
/* normalization factor */
val = sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] );
norm[0] = vr[0]/val;
norm[1] = vr[1]/val;
norm[2] = vr[2]/val;
}
/**
*输入:
* filename:ply文件名
*返回:
* verts:顶点数组
* icnt,tir_index:三角形索引数组
* norm:返表面单位法向量,若无须返回,则置为null
*/
bool LoadPly(char* filename,vector *&verts, vector *&tri_index,vector *&norms){
if(!verts || !tri_index) return false;
ifstream in(filename);
if(!in) return false;
char buffer[300];
size_t vcnt = 0,fcnt = 0;
while(in.getline(buffer,300) && strncmp("end_header",buffer,strlen("end_header")) != 0){
if(strncmp("element vertex",buffer,strlen("element vertex")) == 0){
sscanf(buffer,"element vertex %d",&vcnt);
}else if(strncmp("element face",buffer,strlen("element face")) == 0){
sscanf(buffer,"element face %d",&fcnt);
}
}
if(vcnt == 0 || fcnt == 0) return false;
for(size_t i = 0; i < vcnt; ++i){
float v0,v1,v2;
in.getline(buffer,300);
sscanf(buffer,"%f %f %f %*s",&v0,&v1,&v2);
verts->push_back(v0);
verts->push_back(v1);
verts->push_back(v2);
}
for(size_t i = 0; i < fcnt; ++i){
in.getline(buffer,300);
int u0,u1,u2,u3;
if(buffer[0]=='3'){
sscanf(buffer,"%*d %d %d %d",&u0,&u1,&u2);
tri_index->push_back(u0);
tri_index->push_back(u1);
tri_index->push_back(u2);
if(norms){
float coord0[3]={(*verts)[3*u0],(*verts)[3*u0+1],(*verts)[3*u0+2]};
float coord1[3]={(*verts)[3*u1],(*verts)[3*u1+1],(*verts)[3*u1+2]};
float coord2[3]={(*verts)[3*u2],(*verts)[3*u2+1],(*verts)[3*u2+2]};
float norm[3]; _normalize(coord0,coord1,coord2,norm);
norms->push_back(norm[0]);
norms->push_back(norm[1]);
norms->push_back(norm[2]);
}
}else if(buffer[0]=='4'){
sscanf(buffer,"%*d %d %d %d %d",&u0,&u1,&u2,&u3);
//四边形拆成两个三角形,不知道这样拆有木有问题的?本人没测试过的。
tri_index->push_back(u0);
tri_index->push_back(u1);
tri_index->push_back(u2);
tri_index->push_back(u0);
tri_index->push_back(u2);
tri_index->push_back(u3);
if(norms){
float coord0[3]={(*verts)[3*u0],(*verts)[3*u0+1],(*verts)[3*u0+2]};
float coord1[3]={(*verts)[3*u1],(*verts)[3*u1+1],(*verts)[3*u1+2]};
float coord2[3]={(*verts)[3*u2],(*verts)[3*u2+1],(*verts)[3*u2+2]};
float coord3[3]={(*verts)[3*u3],(*verts)[3*u3+1],(*verts)[3*u3+2]};
float norm[3];
_normalize(coord0,coord1,coord2,norm);
norms->push_back(norm[0]);
norms->push_back(norm[1]);
norms->push_back(norm[2]);
_normalize(coord0,coord2,coord3,norm);
norms->push_back(norm[0]);
norms->push_back(norm[1]);
norms->push_back(norm[2]);
}
}
}
in.close();
return true;
}
你一定见过这只兔子,试一下自己渲染出来吧,效果如图。
加光照效果:
编码请看:http://www.maidoupig.cn