Opengl读取及渲染Obj三维模型

来源:互联网 发布:yc网络语言是什么意思 编辑:程序博客网 时间:2024/05/18 00:01

声明:本文内容及源代码只能作为学习参考用,转载请注明本声明blog.csdn.net/t163ang。

最近为了测试我的碰撞检测代码,需要使用Opengl来导入模型及渲染出来做碰撞,之前我发表一篇文章是对斯坦福模型ply文件渲染的,ply模型资源有限,所以今天看了其它三维模型,发现Obj模型网上有丰富的资源,且表达能力更强,但解析其就相对来讲复杂一些,我看网上一些代码,不是过于简单就是过于复杂,于是自己写了一个,上网下载了几个模型效果可以。渲染调用很简单直接调用RenderObj函数即可。当然如果你要应用到你的项目中,这个代码需要稍微改一改就行罗。另外如果是四边形将会拆成两个三角形,网上好多代码都没这个功能。

#define MAXN 1024*1024#define MAXTEX 32map<string,size_t> ObjMp;size_t vn,vtn,vnn,fn;float V[MAXN][3];float VT[MAXN][2];float VN[MAXN][3];size_t F[MAXN][3][3];size_t TexFacCnt[MAXTEX],TexFacID[MAXTEX],tfn;#pragma comment( lib, "glaux.lib")void _InitMtl(const char *filename){ifstream in(filename);assert(in);ObjMp.clear();char buffer[300],word[300];while(in.getline(buffer,300)){if(strncmp("newmtl",buffer,strlen("newmtl"))==0){sscanf(buffer,"%*s%s",word);}else if(strncmp("map_Kd",buffer+1,strlen("map_Kd"))==0){GLuint texName;glGenTextures(1,&texName);AUX_RGBImageRec *aux = auxDIBImageLoadA(buffer+strlen("\tmap_Kd "));glBindTexture(GL_TEXTURE_2D,texName);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexImage2D(GL_TEXTURE_2D,0,3,aux->sizeX,aux->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,aux->data);ObjMp.insert(make_pair(word,texName));delete aux;}}in.close();}void ReadObj(const char *filename){ifstream in(filename);assert(in);char buffer[300];vn=1;vnn=1;vtn=1;tfn=0;while(in.getline(buffer,300)){if(buffer[0] == 'v'){if(buffer[1]==' '){//vsscanf(buffer,"%*s %f %f %f",&V[vn][0],&V[vn][1],&V[vn][2]);++vn;}else if(buffer[1]=='n' && buffer[2] == ' '){//vnsscanf(buffer,"%*s %f %f %f",&VN[vnn][0],&VN[vnn][1],&VN[vnn][2]);++vnn;}else if(buffer[1]=='t' && buffer[2] == ' '){//vtsscanf(buffer,"%*s %f %f",&VT[vtn][0],&VT[vtn][1]);++vtn;}}else if(buffer[0]=='f'){//fif(buffer[1] == ' '){char str[4][32];int sn = sscanf(buffer,"%*s %s %s %s %s",str[0],str[1],str[2],str[3]);if(sn == 3){for(size_t i = 0; i < 3; ++i){sscanf(str[i],"%d/%d/%d",&F[fn][i][0],&F[fn][i][1],&F[fn][i][2]);}++fn;/*直接渲染,但是当模型很大时,速度将很慢glBegin(GL_TRIANGLES);{size_t iv,it,in;for(size_t i = 0; i < 3; ++i){sscanf(str[i],"%d/%d/%d",&iv,&it,&in);glNormal3fv(VN[in]);glTexCoord2fv(VT[it]);glVertex3fv(V[iv]);}}glEnd();*/}else if(sn == 4){//拆分成两个三角形,四边形0123分成Tri012和Tri023for(size_t i = 0; i < 3; ++i){sscanf(str[i],"%d/%d/%d",&F[fn][i][0],&F[fn][i][1],&F[fn][i][2]);}++fn;for(size_t i = 0; i < 3; ++i){sscanf(str[i!=0?i+1:0],"%d/%d/%d",&F[fn][i][0],&F[fn][i][1],&F[fn][i][2]);}++fn;/*glBegin(GL_TRIANGLES);{size_t iv,it,in;for(size_t i = 0; i < 3; ++i){sscanf(str[i],"%d/%d/%d",&iv,&it,&in);glNormal3fv(VN[in]);glTexCoord2fv(VT[it]);glVertex3fv(V[iv]);}for(size_t i = 0; i < 3; ++i){sscanf(str[i!=0?i+1:0],"%d/%d/%d",&iv,&it,&in);glNormal3fv(VN[in]);glTexCoord2fv(VT[it]);glVertex3fv(V[iv]);}}glEnd();*/}else{assert(false);}}}else if(buffer[0]=='m'){//mtllibif(buffer[1]=='t' && buffer[2]=='l' && buffer[3]=='l'&&buffer[4]=='i' && buffer[5] == 'b' && buffer[6] == ' '){_InitMtl(buffer+strlen("mtllib "));}}else if(buffer[0]=='u'){//usemtlif(buffer[1]=='s' && buffer[2]=='e' && buffer[3]=='m'&&buffer[4]=='t' && buffer[5] == 'l' && buffer[6] == ' '){string key = string(buffer+strlen("usemtl "));TexFacCnt[tfn]=fn;//记录信息,以后渲染使用if(ObjMp.find(key) != ObjMp.end()){//直接在读文件时渲染,处理很方便,但渲染更新速度慢//glBindTexture(GL_TEXTURE_2D,ObjMp[key]);TexFacID[tfn] = ObjMp[key];}else{//glBindTexture(GL_TEXTURE_2D,0);TexFacID[tfn] = 0;}++tfn;}}}}void RenderObj(const char* filename){static bool firstRender = true;if(firstRender){ReadObj(filename);firstRender = false;}glBegin(GL_TRIANGLES);{for(size_t i =0,j = 0; i < fn; ++i){if(j < tfn && i == TexFacCnt[j]){glBindTexture(GL_TEXTURE_2D,TexFacID[j]);++j;}glNormal3fv(VN[F[i][0][2]]);glTexCoord2fv(VT[F[i][0][1]]);glVertex3fv(V[F[i][0][0]]);glNormal3fv(VN[F[i][1][2]]);glTexCoord2fv(VT[F[i][1][1]]);glVertex3fv(V[F[i][1][0]]);glNormal3fv(VN[F[i][2][2]]);glTexCoord2fv(VT[F[i][2][1]]);glVertex3fv(V[F[i][2][0]]);}}glEnd();}

随便下载一个模型渲染出来效果图:


1 1