载入PLY模型 C++
之前在网上查找了很长一段时间关于ply模型载入的资料,发现对鹿鹿鹿有用的实在太少,有个挺火的代码各个网站都有转载,但可惜的是鹿鹿鹿没有他的bird.ply模型,并且他代码也不是纯C++的,有很多C的东西。昨天偶然翻墙到一个貌似台湾的博客,贴出了源代码,试了试没想到还跑出来了。所以这里分享一下,希望给也在寻找ply模型载入的小伙伴一点帮助。代码来自痞客邦里面名叫tinylin的博主,转载请声明。
/* 2: 操作說明: 3: 鍵盤按下 4: r=會變成紅色 5: g=會變成綠色 6: b=會變成藍色 7: p=ploygon組成 8: l=line組成 9: model本身會自動旋轉 10: */ #include <iostream> #include <fstream> #include <string> #include <GL/glut.h> #include <math.h> using namespace std; void LoadPly(char *file_name,int style);//讀取並畫出ply函式 double r_ang=0.5;//旋轉角度變數 double R=255.0, G=0.0, B=0.0;//顏色儲存變數 int style=GL_POLYGON;//畫出model的方式 /*lighting 變數*/ const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat light_position[] = { 2.0f, 5.0f, 15.0f, 0.0f }; const GLfloat mat_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat high_shininess[] = { 1.0f }; void LoadPly(char *file_name,int style) { ifstream fin ( file_name, ios_base::in );//開檔 if ( !fin.is_open ( ) ) { cout << "Cannot read the file." << endl; cout << "Please check again." << endl; exit(0); } string str; int vertex, face; char ch; /*讀取header*/ while ( !fin.eof ( ) ) { fin.get ( ch ); if( ch != " " && ch != " " && ch != " " ) { str.push_back ( ch ); } else { //取得vertex個數 if(str == "vertex") { str.clear ( ); getline ( fin, str, " " ); vertex = atoi(str.c_str()); } //取得face個數 else if(str == "face") { str.clear ( ); getline ( fin, str, " " ); face = atoi(str.c_str()); } else if(str == "end_header") { str.clear ( ); break; } else str.clear ( ); } } //動態產生array double *vertex_arrayX = new double[vertex]; double *vertex_arrayY = new double[vertex]; double *vertex_arrayZ = new double[vertex]; int pos = 0; int counter = 0; double number; double max_edge = 0; static double temp_max = 0; /*讀取Vertex*/ while ( !fin.eof ( ) ) { fin.get ( ch ); if( ch != " " && ch != " " && ch != " " ) str.push_back ( ch ); else { if(counter == vertex) break; /*儲存vertex資料*/ if(str == "") continue; else if(pos%3 == 0) { number = atof(str.c_str()); vertex_arrayX[counter] = number; str.clear ( ); } else if(pos%3 == 1) { number = atof(str.c_str()); vertex_arrayY[counter] = number; str.clear ( ); } else if(pos%3 == 2) { number = atof(str.c_str()); vertex_arrayZ[counter] = number; str.clear ( ); counter++; } pos++; //紀錄最大的邊 if(abs((int)number) > max_edge) max_edge = abs((int)number); } } int point[4]; int i = 0; counter = 0; /*畫Polygon*/ while ( !fin.eof ( ) ) { fin.get ( ch ); if( ch != " " && ch != " " && ch != " " ) str.push_back ( ch ); else { if(counter == face) break; if(ch == " ") { // 計算法線向量 (打光) GLfloat vc1[3],vc2[3]; GLfloat a,b,c; GLdouble r; vc1[0]= vertex_arrayX[point[2]] - vertex_arrayX[point[1]]; vc1[1]= vertex_arrayY[point[2]] - vertex_arrayY[point[1]]; vc1[2]= vertex_arrayZ[point[2]] - vertex_arrayZ[point[1]]; vc2[0]= vertex_arrayX[point[3]] - vertex_arrayX[point[1]]; vc2[1]= vertex_arrayY[point[3]] - vertex_arrayY[point[1]]; vc2[2]= vertex_arrayZ[point[3]] - vertex_arrayZ[point[1]]; a = vc1[1] * vc2[2] - vc2[1] * vc1[2]; b = vc2[0] * vc1[2] - vc1[0] * vc2[2]; c = vc1[0] * vc2[1] - vc2[0] * vc1[1]; r = sqrt( a * a + b* b + c * c); float nor[3]; nor[0] = a / r; nor[1] = b / r; nor[2] = c / r; glNormal3f(nor[0],nor[1],nor[2]); //畫出所有face glBegin(style); for(int i=1;i<=point[0];i++) glVertex3f(vertex_arrayX[point[i]], vertex_arrayY[point[i]],vertex_arrayZ[point[i]]); glEnd(); counter++; } else if(str == "") continue; else { point[i%4] = atoi(str.c_str()); i++; str.clear ( ); } } } fin.close(); //調整視角 if(max_edge > temp_max) { glLoadIdentity (); glOrtho(-(max_edge*2), (max_edge*2), -(max_edge*2), (max_edge*2), -(max_edge*2), (max_edge*2)); } temp_max = max_edge; } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glRotatef(r_ang, 0.0, 1.0, 1.0); glColor3f(R,G,B); LoadPly("ant.ply",style); glFlush(); glutSwapBuffers(); } void init() { glClearColor (0.0, 0.0, 0.0, 1.0); glLoadIdentity (); glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0); } void keyboard(unsigned char key, int x, int y) { //按esc離開 switch (key) { case 27 : exit(0); break; case "r": R=255;G=0;B=0; break; case "g": R=0;G=255;B=0; break; case "b": R=0;G=0;B=255; break; case "p": style = GL_POLYGON; break; case "l": style = GL_LINES; break; } glutPostRedisplay(); } void idle(void) { glutPostRedisplay(); } int main(int argc, char** argv) { glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (600, 600); glutInitWindowPosition (300, 50); glutCreateWindow("Load Ply Model"); glutDisplayFunc(display); glutIdleFunc(idle); glutKeyboardFunc(keyboard);//偵測keyboard init(); //使用lighting 相關函式 glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess); glutMainLoop(); return EXIT_SUCCESS; }
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了