载入PLY模型 C++

来源:互联网 发布:mysql官网下载免费版 编辑:程序博客网 时间:2024/05/29 15:30

之前在网上查找了很长一段时间关于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 != '\t' && ch != '\n' ){str.push_back ( ch );   }else{//取得vertex個數 if(str == "vertex"){str.clear ( );getline ( fin, str, '\n' ); vertex = atoi(str.c_str());       }//取得face個數 else if(str == "face"){str.clear ( );getline ( fin, str, '\n' );  face = atoi(str.c_str());             }else if(str == "end_header"){str.clear ( );     break;     }elsestr.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 != '\t' && ch != '\n' )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 != '\t' && ch != '\n' )str.push_back ( ch );else{if(counter == face)break;  if(ch == '\n'){// 計算法線向量 (打光)    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]); //畫出所有faceglBegin(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; }


1 0
原创粉丝点击