载入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
- 载入PLY模型 C++
- .ply模型格式解析与Loader编写
- 载入动画模型
- OpenGL读取PLY模型文件并绘制 Read and draw ply model by OpenGL
- Opengl读取及渲染斯坦福三维ply模型
- MeshLab的ply模型转化为Ogre所需的mesh模型(一)
- MeshLab的ply模型转化为Ogre所需的mesh模型(二)
- C/C++ 参数载入问题
- XNA学习(二) 载入3D模型
- iOS 载入3d模型 OpenGL ES
- Drect3D---多游戏模型的载入
- cesiumjs载入3D模型glTF
- Tensorflow 同时载入多个模型
- pcl:三维模型obj格式转成pcl常用点云处理格式.pcd+matlab:.ply<->.pcd+其他.stl,.obj,.ply等三维格式互相转化方法
- PLY文件
- PLY文件格式
- PLY格式
- ply 文件格式
- 将Bitmmap转换成圆形位图
- 回车的传说
- C语言判断输入的字符串是否为回文结构
- JS基础—选项卡套选项卡(函数传参)
- Linux命令备忘实例(17)——cURL
- 载入PLY模型 C++
- ImageLoader在适配器中的知识点
- 文件操作fopen等接口
- Python多线程编程及同步处理
- python知识点
- bzoj1143 祭祀 最大匹配
- XmlPullParser解析xml
- NSURLSESSION的使用
- HttpURLConnection————Post