首页 > 其他 > 详细

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

时间:2014-04-16 11:16:49      阅读:821      评论:0      收藏:0      [点我收藏+]

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;
}

结果

bubuko.com,布布扣

bubuko.com,布布扣

OpenGL读取PLY模型文件并绘制 Read ply model and draw it by OpenGL,布布扣,bubuko.com

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

原文:http://blog.csdn.net/pyang1989/article/details/23799297

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!