openGL 解析ply文件并且显示三维模型

一、ply文件简介

ply文件是一种用于描述图形结构的文件。一般包括:头部、顶点列表、面片列表、其他元素列表等。

例如下面这个ply文件描述了一个cube。

复制代码

ply
format ascii 1.0
comment made by anonymous
comment this file is a cube
element vertex 8
property float32 x
property float32 y
property float32 z
element face 12
property list uint8 int32 vertex_index
end_header
0 0 0
0 0 0.01
0 0.01 0.01
0 0.01 0
0.01 0 0
0.01 0 0.01
0.01 0.01 0.01
0.01 0.01 0
3 0 1 2
3 0 3 2
3 7 9 5
3 7 4 5
3 0 4 5
3 0 1 5
3 1 5 6
3 1 2 6
3 2 6 7
3 2 3 7
3 1 7 4
3 3 0 4

复制代码

二、ply文件的解析及用openGL显示

ply的文件格式比较简单,我们只需要对其中的信息进行提取,在调用openGL中相应的函数就可以实现显示ply模型了。

代码:

复制代码

 1 #ifndef PLYREADER_H_
 2 #define PLYREADER_H_
 3 
 4 #include <GL/glut.h>
 5 #include <GL/glu.h>
 6 #include <GL/gl.h>
 7 #include <vector>
 8 using namespace std;
 9 
10 struct SModelData
11 {
12     vector <float> vecFaceTriangles; // = face * 9
13     vector <float> vecFaceTriangleColors; // = face * 9
14     int iTotalConnectedTriangles;
15 };
16 
17 class CPLYLoader
18 {
19 public:
20     CPLYLoader();
21     bool LoadModel(char * filename);
22     void Draw();
23 private:
24     float * mp_vertexXYZ;
25     float * mp_vertexRGB;
26     int m_totalConnectedQuads;
27     int m_totalConnectedPoints;
28     int m_totalFaces;
29     SModelData m_ModelData;
30 };
31 
32 #endif

复制代码

复制代码

  1 #include "stdafx.h"
  2 #include "PLYLoader.h"
  3 
  4 CPLYLoader::CPLYLoader()
  5 {
  6     this->m_totalConnectedQuads = 0;
  7     this->m_totalConnectedPoints = 0;
  8     this->m_ModelData.iTotalConnectedTriangles = 0;
  9 }
 10 
 11 bool CPLYLoader::LoadModel(char * filename)
 12 {
 13     printf("Loading %s...\n", filename);
 14     char * pch = strstr(filename, ".ply");
 15     if (pch != NULL)
 16     {
 17         FILE * file = fopen(filename, "r");
 18         if (!file)
 19         {
 20             printf("load PLY file %s failed\n", filename);
 21             return false;
 22         }
 23         fseek(file, 0, SEEK_END);
 24         long fileSize = ftell(file);
 25         try
 26         {
 27             mp_vertexXYZ = (float*)malloc(fileSize);
 28             mp_vertexRGB = (float*)malloc(fileSize);
 29         }
 30         catch (char *)
 31         {
 32             return false;
 33         }
 34         if (mp_vertexXYZ == NULL || mp_vertexRGB == NULL) return false;
 35         fseek(file, 0, SEEK_SET);
 36         if (file)
 37         {
 38             char buffer[1000];
 39             fgets(buffer, 300, file);            
 40             //READ HEADER
 41             while (strncmp("element vertex", buffer, strlen("element vertex")) != 0)
 42             {
 43                 fgets(buffer, 300, file);        
 44             }
 45             strcpy(buffer, buffer + strlen("element vertex"));
 46             sscanf(buffer, "%i", &this->m_totalConnectedPoints);
 47             printf("first we get %d vertexs\n", this->m_totalConnectedPoints);
 48             //Find the number of vertexes
 49             fseek(file, 0, SEEK_SET);
 50             while (strncmp("element face", buffer, strlen("element face")) != 0)
 51             {
 52                 fgets(buffer, 300, file);        
 53             }
 54             strcpy(buffer, buffer + strlen("element face"));
 55             sscanf(buffer, "%i", &this->m_totalFaces);
 56             printf("second we get %d faces\n", this->m_totalFaces);
 57             //Go to end_header
 58             while (strncmp("end_header", buffer, strlen("end_header")) != 0)
 59             {
 60                 fgets(buffer, 300, file);            
 61             }
 62             //Read vertices
 63             int i = 0;
 64             for (int iterator = 0; iterator < this->m_totalConnectedPoints; iterator++)
 65             {
 66                 fgets(buffer, 300, file);
 67                 sscanf(buffer, "%f %f %f", &mp_vertexXYZ[i], &mp_vertexXYZ[i + 1], &mp_vertexXYZ[i + 2]);
 68                 i += 3;
 69             }
 70             //Read faces
 71             for (int iterator = 0; iterator < this->m_totalFaces; iterator++)
 72             {
 73                 fgets(buffer, 300, file);
 74                 //Triangular patch
 75                 if (buffer[0] == '3')
 76                 {
 77                     int vertex1 = 0, vertex2 = 0, vertex3 = 0;
 78                     buffer[0] = ' ';
 79                     sscanf(buffer, "%i%i%i", &vertex1, &vertex2, &vertex3);
 80                     //point
 81                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex1]);
 82                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex1 + 1]);
 83                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex1 + 2]);
 84                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex2]);
 85                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex2 + 1]);
 86                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex2 + 2]);
 87                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex3]);
 88                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex3 + 1]);
 89                     m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex3 + 2]);
 90                     //color
 91                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 92                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 93                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 94                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 95                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 96                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 97                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 98                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
 99                     m_ModelData.vecFaceTriangleColors.push_back(1.0);
100                     m_ModelData.iTotalConnectedTriangles += 3;
101                 }
102             }
103             fclose(file);
104             printf("%s Loaded!\n", filename);
105             return true;
106         }
107         else
108         {
109             printf("File can't be opened\n");
110             return false;
111         }
112     }
113     else
114     {
115         printf("File does not have a ply extension.\n");
116         return false;
117     }
118 }
119 
120 void CPLYLoader::Draw() //implemented in GLPainter, not called again
121 {
122     glVertexPointer(3, GL_FLOAT, 0, m_ModelData.vecFaceTriangles.data());
123     glColorPointer(3, GL_FLOAT, 0, m_ModelData.vecFaceTriangleColors.data());
124     glDrawArrays(GL_TRIANGLES, 0, m_ModelData.iTotalConnectedTriangles);
125 }

复制代码

复制代码

 1 #include "stdafx.h"
 2 #include "PlyLoader.h"
 3 #include <gl/glut.h>
 4 
 5 CPLYLoader plyLoader;
 6 
 7 void init()
 8 {
 9     glClearColor(0, 0, 0, 0);
10     glEnableClientState(GL_VERTEX_ARRAY);
11     glEnable(GL_COLOR_ARRAY);
12     plyLoader.LoadModel("dragon.ply");
13 }
14 
15 void display()
16 {
17     glClear(GL_COLOR_BUFFER_BIT);
18     plyLoader.Draw();
19     glFlush();
20 }
21 
22 int _tmain(int argc, _TCHAR* argv[])
23 {
24     glutInit(&argc, (char **)argv);
25     glutInitWindowSize(500, 500);
26     glutInitWindowPosition(100, 100);
27     glutCreateWindow("load model");
28     init();
29     glutDisplayFunc(display);
30     glutMainLoop();
31     return 0;
32 }

转:https://www.cnblogs.com/huoxiayu/p/5483477.html

猜你喜欢

转载自blog.csdn.net/eric_e/article/details/84706311