您的位置:首页 > 运维架构

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

2016-05-11 20:45 459 查看
一、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模型了。

代码:

#ifndef PLYREADER_H_
#define PLYREADER_H_

#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <vector>
using namespace std;

struct SModelData
{
vector <float> vecFaceTriangles; // = face * 9
vector <float> vecFaceTriangleColors; // = face * 9
int iTotalConnectedTriangles;
};

class CPLYLoader
{
public:
CPLYLoader();
bool LoadModel(char * filename);
void Draw();
private:
float * mp_vertexXYZ;
float * mp_vertexRGB;
int m_totalConnectedQuads;
int m_totalConnectedPoints;
int m_totalFaces;
SModelData m_ModelData;
};

#endif


#include "stdafx.h"
#include "PLYLoader.h"

CPLYLoader::CPLYLoader()
{
this->m_totalConnectedQuads = 0;
this->m_totalConnectedPoints = 0;
this->m_ModelData.iTotalConnectedTriangles = 0;
}

bool CPLYLoader::LoadModel(char * filename)
{
printf("Loading %s...\n", filename);
char * pch = strstr(filename, ".ply");
if (pch != NULL)
{
FILE * file = fopen(filename, "r");
if (!file)
{
printf("load PLY file %s failed\n", filename);
return false;
}
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
try
{
mp_vertexXYZ = (float*)malloc(fileSize);
mp_vertexRGB = (float*)malloc(fileSize);
}
catch (char *)
{
return false;
}
if (mp_vertexXYZ == NULL || mp_vertexRGB == NULL) return false;
fseek(file, 0, SEEK_SET);
if (file)
{
char buffer[1000];
fgets(buffer, 300, file);
//READ HEADER
while (strncmp("element vertex", buffer, strlen("element vertex")) != 0)
{
fgets(buffer, 300, file);
}
strcpy(buffer, buffer + strlen("element vertex"));
sscanf(buffer, "%i", &this->m_totalConnectedPoints);
printf("first we get %d vertexs\n", this->m_totalConnectedPoints);
//Find the number of vertexes
fseek(file, 0, SEEK_SET);
while (strncmp("element face", buffer, strlen("element face")) != 0)
{
fgets(buffer, 300, file);
}
strcpy(buffer, buffer + strlen("element face"));
sscanf(buffer, "%i", &this->m_totalFaces);
printf("second we get %d faces\n", this->m_totalFaces);
//Go to end_header
while (strncmp("end_header", buffer, strlen("end_header")) != 0)
{
fgets(buffer, 300, file);
}
//Read vertices
int i = 0;
for (int iterator = 0; iterator < this->m_totalConnectedPoints; iterator++)
{
fgets(buffer, 300, file);
sscanf(buffer, "%f %f %f", &mp_vertexXYZ[i], &mp_vertexXYZ[i + 1], &mp_vertexXYZ[i + 2]);
i += 3;
}
//Read faces
for (int iterator = 0; iterator < this->m_totalFaces; iterator++)
{
fgets(buffer, 300, file);
//Triangular patch
if (buffer[0] == '3')
{
int vertex1 = 0, vertex2 = 0, vertex3 = 0;
buffer[0] = ' ';
sscanf(buffer, "%i%i%i", &vertex1, &vertex2, &vertex3);
//point
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex1]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex1 + 1]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex1 + 2]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex2]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex2 + 1]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex2 + 2]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex3]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex3 + 1]);
m_ModelData.vecFaceTriangles.push_back(mp_vertexXYZ[3 * vertex3 + 2]);
//color
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.vecFaceTriangleColors.push_back(1.0);
m_ModelData.iTotalConnectedTriangles += 3;
}
}
fclose(file);
printf("%s Loaded!\n", filename);
return true;
}
else
{
printf("File can't be opened\n");
return false;
}
}
else
{
printf("File does not have a ply extension.\n");
return false;
}
}

void CPLYLoader::Draw() //implemented in GLPainter, not called again
{
glVertexPointer(3, GL_FLOAT, 0, m_ModelData.vecFaceTriangles.data());
glColorPointer(3, GL_FLOAT, 0, m_ModelData.vecFaceTriangleColors.data());
glDrawArrays(GL_TRIANGLES, 0, m_ModelData.iTotalConnectedTriangles);
}


#include "stdafx.h"
#include "PlyLoader.h"
#include <gl/glut.h>

CPLYLoader plyLoader;

void init()
{
glClearColor(0, 0, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_COLOR_ARRAY);
plyLoader.LoadModel("dragon.ply");
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);
plyLoader.Draw();
glFlush();
}

int _tmain(int argc, _TCHAR* argv[])
{
glutInit(&argc, (char **)argv);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("load model");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}


代码参考来源于互联网。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: