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

OpenGL读取PLY模型文件并绘制 Read and draw ply model by OpenGL

2014-04-16 00:42 633 查看
Ply文件由MeshLab导出生成,格式可能和其他软件导出的有出入。

本来想把模型文件贴上来,但是找了一下好像不能上传,希望着可留言。

这里贴一下模型文件的开头部分。

-------------------------------------------------------

ply

format ascii 1.0

comment VCGLIB generated

element vertex 6479

property float x

property float y

property float z

property float nx

property float ny

property float nz

property int flags

property uchar red

property uchar green

property uchar blue

property uchar alpha

element face 12954

property list uchar int vertex_indices

property int flags

end_header

0.0363526 0.0894518 0.0166275 -2.58589 -5.26492 -2.22414 0 175 160 84 255 

0.0389934 0.088225 0.0166275 -2.52566 -5.33 -2.15753 0 170 156 88 255 

0.0389934 0.0894518 0.0138336 -2.41584 -5.1918 -2.5521 0 146 145 86 255 

0.0340731 0.0894518 0.0200012 -2.865 -5.39322 -1.43764 0 174 151 78 255 

0.0356197 0.0886338 0.0200012 -2.74755 -5.42387 -1.53245 0 168 145 74 255 

0.0356197 0.0894518 0.0175829 -2.64306 -5.36739 -1.90754 0 171 156 75 255 

......

-------------------------------------------------------

PlyLoader.h

#ifndef PLYREADER_H_
#define PLYREADER_H_

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

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

class CPLYLoader
{
public:
CPLYLoader();
int LoadModel(char *filename);
void Draw();

private:
float* mp_vertexXYZ;
float* mp_vertexNorm;
float* mp_vertexRGB;
int m_totalConnectedQuads;
int m_totalConnectedPoints;
int m_totalFaces;
SModelData m_ModelData;
};

#endif


PlyLoader.cpp

#include "PLYLoader.h"

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

int 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 (ftell(file));
mp_vertexNorm = (float*) malloc (ftell(file));
mp_vertexRGB = (float*) malloc(ftell(file));
}
catch (char* )
{
return -1;
}
if (mp_vertexXYZ == NULL) return -1;
if (mp_vertexNorm == NULL) return -2;
if (mp_vertexRGB == NULL) return -3;
fseek(file,0,SEEK_SET);

if (file)
{
int i = 0;
int temp = 0;
int quads_index = 0;
int triangle_index = 0;
int normal_index = 0;
int colorIndex = 0;
char buffer[1000];

fgets(buffer,300,file);			// ply

// READ HEADER
// -----------------

// Find number of vertexes
while (  strncmp( "element vertex", buffer,strlen("element vertex")) != 0  )
{
fgets(buffer,300,file);			// format
}
strcpy(buffer, buffer+strlen("element vertex"));
sscanf(buffer,"%i", &this->m_totalConnectedPoints);

// Find number of vertexes
fseek(file,0,SEEK_SET);
while (  strncmp( "element face", buffer,strlen("element face")) != 0  )
{
fgets(buffer,300,file);			// format
}
strcpy(buffer, buffer+strlen("element face"));
sscanf(buffer,"%i", &this->m_totalFaces);

// go to end_header
while (  strncmp( "end_header", buffer,strlen("end_header")) != 0  )
{
fgets(buffer,300,file);			// format
}

//----------------------

// read vertices
i =0;
for (int iterator = 0; iterator < this->m_totalConnectedPoints; iterator++)//3488
{
char tmp[1];
fgets(buffer,300,file);

sscanf(buffer,"%f %f %f %f %f %f %c %f %f %f", &mp_vertexXYZ[i], &mp_vertexXYZ[i+1], &mp_vertexXYZ[i+2],
&mp_vertexNorm[i], &mp_vertexNorm[i+1], &mp_vertexNorm[i+2],
tmp,
&mp_vertexRGB[i], &mp_vertexRGB[i+1],  &mp_vertexRGB[i+2]);
i += 3;
}

// read faces
i =0;
for (int iterator = 0; iterator < this->m_totalFaces; iterator++)//6920
{
fgets(buffer,300,file);

if (buffer[0] == '3')
{
int vertex1 = 0, vertex2 = 0, vertex3 = 0;
buffer[0] = ' ';
sscanf(buffer,"%i%i%i", &vertex1,&vertex2,&vertex3 );//number of vertex eg:5,7,6

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]);

m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex1]  / 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex1+1]/ 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex1+2]/ 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex2]  / 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex2+1]/ 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex2+2]/ 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex3]  / 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex3+1]/ 255.0f);
m_ModelData.vecFaceTriangleColors.push_back( mp_vertexRGB[3*vertex3+2]/ 255.0f);

m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex1]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex1+1]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex1+2]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex2]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex2+1]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex2+2]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex3]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex3+1]);
m_ModelData.vecNormals.push_back( mp_vertexNorm[3*vertex3+2]);

triangle_index += 9;
m_ModelData.iTotalConnectedTriangles += 3;
}

i += 3;
}

fclose(file);
printf("%s Loaded!\n",filename);

}

else
{
printf("File can't be opened\n");
}
}
else
{
printf("File does not have a .PLY extension. ");
}

return 0;
}

void CPLYLoader::Draw() //implemented in GLPainter, not called again
{
if (m_ModelData.vecFaceTriangleColors.empty())
{
cout << "model data is null"<<endl;
exit(-1);
}

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3,GL_FLOAT,	0,m_ModelData.vecFaceTriangles.data());
glColorPointer(3,GL_FLOAT,0,m_ModelData.vecFaceTriangleColors.data());
glNormalPointer(GL_FLOAT, 0, m_ModelData.vecNormals.data());
glDrawArrays(GL_TRIANGLES, 0, m_ModelData.iTotalConnectedTriangles);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}


Main.cpp

#include "PLYLoader.h"
int width = 640;
int height = 480;

CPLYLoader plyLoader;

void Initialize()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable( GL_DEPTH_TEST );
plyLoader.LoadModel("bird.ply");
}

void Reshape(int w, int h)
{
width = w;
height = h;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)width / (double)height, 1.0, 1000.0);
}

void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.7, -0.3, 0);
glRotatef(280,1,0,0);
glRotatef(80,0,0,1);
glScalef(5, 5, 5);
plyLoader.Draw();
glutSwapBuffers();
}

int main( int argc, char **argv )
{
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(width, height);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutCreateWindow("Load Model");
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);

Initialize();

glutMainLoop();

return 0;
}

结果

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