obj文件的理解请参考:http://foolog.net/?p=941
要注意一点,obj文件中面的保存,有的是按照三角形(也就是只有三个点),有的是按照空间四边形保存(包含四个点),这里是按照四个点来的,注释中已经给出。
#ifndef GLUT_DISABLE_ATEXIT_HACK #define GLUT_DISABLE_ATEXIT_HACK #endif #define GLEW_STATIC #include <GL/glew.h> #include <GL/wglew.h> #include <GL/freeglut.h> #include <vector> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> //for matrices #include <glm/gtc/type_ptr.hpp> //undefine if u want to use the default bending constraint of pbd #include<sstream> #include <fstream> #include<iostream> using namespace std; GLfloat rtx = 0.0f, rty = 0.0f, rtz = 0.0; GLfloat step = 0.1; //float exp1 = 1e-3; const int GRID_SIZE = 10; GLint viewport[4]; GLdouble PP[16]; int v_num; //记录点的数量 int vn_num;//记录法线的数量 int vt_num;// int f_num; //记录面的数量 GLfloat **vArr; //存放点的二维数组 GLfloat **vnArr;//存放法线的二维数组 int **fvArr; //存放面顶点的二维数组 int **fnArr; //存放面法线的二维数组 int readfile(string addrstr) //将文件内容读到数组中去 { int i; string s1; float f2,f3,f4; vArr=new GLfloat*[v_num]; for (i=0; i<v_num; i++) { vArr[i]=new GLfloat[3]; } vnArr=new GLfloat*[vn_num]; for (i=0; i<vn_num; i++) { vnArr[i]=new GLfloat[3]; } fvArr=new int*[f_num]; fnArr=new int*[f_num]; for (i=0; i<f_num; i++) { fvArr[i]=new int[4]; fnArr[i]=new int[3]; } ifstream infile(addrstr.c_str()); string sline;//每一行 int ii=0,jj=0,kk=0; while(getline(infile,sline)) { if(sline[0]=='v') { if(sline[1]=='n')//vn { istringstream sin(sline); sin>>s1>>f2>>f3>>f4; vnArr[ii][0]=f2; vnArr[ii][1]=f3; vnArr[ii][2]=f4; ii++; } else if(sline[1] == 't'){} else//v { istringstream sin(sline); sin>>s1>>f2>>f3>>f4; vArr[jj][0]=f2; vArr[jj][1]=f3; vArr[jj][2]=f4; jj++; } } if (sline[0]=='f') //读取面 { istringstream in(sline); GLfloat a; in>>s1;//去掉前缀f int i,k; //点数改这里 for(i=0; i<4; i++) { in>>s1; // cout<<s1<<endl; printf("%s\n",s1.c_str()); //取得顶点索引和法线索引 a=0; for(k=0; s1[k]!='/'; k++) { a=a*10+(s1[k]-48); } fvArr[kk][i]=a; a=0; for(k=k+2; s1[k]; k++) { a=a*10+(s1[k]-48);; } fnArr[kk][i]=a; } kk++; } } return 0; } void getLineNum(string addrstr){ //获取点数以及面数 // cout<<addrstr.c_str()<<endl; v_num = vn_num = f_num = vt_num = 0; ifstream infile(addrstr.c_str()); string sline;//每一行 while(getline(infile, sline)){ // cout<<sline<<endl; printf("%s\n",sline.c_str()); if(sline[0]=='v'){ if(sline[1] == 'n'){ vn_num ++; }else if(sline[1] =='t'){ //vt vt_num ++; }else{ v_num ++; } }else{ if(sline[0] == 'f'){ f_num ++; } } } } string s1; GLfloat f2,f3,f4; void DrawGrid() { glBegin(GL_LINES); glColor3f(0.5f, 0.5f, 0.5f); for(int i=-GRID_SIZE;i<=GRID_SIZE;i++) { glVertex3f((float)i,0,(float)-GRID_SIZE); glVertex3f((float)i,0,(float)GRID_SIZE); glVertex3f((float)-GRID_SIZE,0,(float)i); glVertex3f((float)GRID_SIZE,0,(float)i); } glEnd(); } void draw(void) { cout<<f_num; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0,0,-10); glRotatef(15,1,0,0); DrawGrid(); glBegin(GL_LINES); glColor3f(1, 1, 1); for(int i = 0; i < f_num; i++){ int a0,a1,a2,a3; a0 = fvArr[i][0]-1; a1 = fvArr[i][1]-1; a2 = fvArr[i][2]-1; //点数改这里 a3 = fvArr[i][3]-1; glVertex3f(vArr[a0][0],vArr[a0][1],vArr[a0][2]); glVertex3f(vArr[a1][0],vArr[a1][1],vArr[a1][2]); cout<<vArr[a0][0]<<" line "<<vArr[a1][0]<<endl; glVertex3f(vArr[a1][0],vArr[a1][1],vArr[a1][2]); glVertex3f(vArr[a2][0],vArr[a2][1],vArr[a2][2]); cout<<vArr[a1][0]<<" line "<<vArr[a2][0]<<endl; glVertex3f(vArr[a2][0],vArr[a2][1],vArr[a2][2]); //点数改这里 glVertex3f(vArr[a3][0],vArr[a3][1],vArr[a3][2]); glVertex3f(vArr[a3][0],vArr[a3][1],vArr[a3][2]); cout<<vArr[a2][0]<<" line "<<vArr[a0][0]<<endl; glVertex3f(vArr[a0][0],vArr[a0][1],vArr[a0][2]); } glEnd(); glutSwapBuffers(); } void OnReshape(int nw, int nh) { glViewport(0,0,nw, nh); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, (GLfloat)nw / (GLfloat)nh, 1.f, 100.0f); glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_PROJECTION_MATRIX, PP); glMatrixMode(GL_MODELVIEW); } //float step = 0.001; int main(int argc, char * argv[]) { getLineNum("yifu.obj"); readfile("yifu.obj"); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100, 100); glutInitWindowSize(1024, 1024); glutCreateWindow("Hello OpenGL"); // init(); glutDisplayFunc(draw); // glutIdleFunc(draw); //指定程序空闲时调用函数 glutReshapeFunc(OnReshape); //指定窗口形状变化时的回调函数 glEnable(GL_DEPTH_TEST); glutMainLoop(); return 0; }
相关推荐
该工程采用Qt3D模块加载obj模型文件,最终将模型显示在窗口中。 环境:qt:5.9.6 系统:win10 64Bit obj文件:自带一份
基于Qt+OpenGL 实现的3D模型obj文件加载以及纹理贴图,未使用第三方库,根据obj文件的格式,逐行解析并读取,加载到顶点缓冲区中,适合学习OBJ模型加载的同学参考。
Qt6.2.0 通过opengl库加载多个obj文件显示,效果和教程看我博客
1.openGL加载obj三维模型, 2.并且在模型上添加光照 3.Blinn-Phong 着色
Android通过opengl显示obj模型
Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种类型的3D模型,.glb .obj 等;Qt+opengl加载各种...
本项目主要通过利用OpenGL读取obj模型,并且加载obj模型 暂时没有用到关于纹理和法向量,只是先通过顶点坐标加载模型。
openGL加载obj三维模型,带纹理贴图,并加入鼠标键盘控制,使用到glew、glfw、soil2库,不用配置,完全可以运行。使用vs2019开发环境
1. 基于QT平台,使用OpenGL进行obj文件加载显示; 2. 使用鼠标对场景进行缩放、移动、旋转交互; 本资源有对应的项目介绍,详见同名CSDN博文。《基于QT使用OpenGL,加载obj模型,进行鼠标交互》 本项目资源整体框架...
C opengl加载并渲染obj模型文件
可以用QT运行,加载OpenGL,读取obj模型,并加载多幅纹理。
这是一个简单obj模型 其中使用到的只有三个文件 还带有示例代码 大家随便下载
OpenGL ES Obj 3D示例模型,在网上搜索和下载OBJ模型非常麻烦,找了几个,干脆打个包给大家分享一下。可以结合OBJ2OpenGL在iPhone上使用OpenGL Es尝试加载一下试试。
python环境pyqt框体下读取显示obj模型文件 主要是可以在pyqt GUI里显示。 基于pyqt 5.0 在vscode下调试可用。
添加附加依赖库,和模型图片资源,以及模型obj文件。使用opengl库3d呈现以及贴图。obj文件初步解析
使用C#WinForm加载OBJ的三维模型文件并显示出来,支持鼠标拾取模型,支持三维场景漫游,支持自动计算帧率,。
现代OpenGL,利用Assimp进行3d模型加载的一个Demo,提供了两个3d模型,能很好的加载含纹理的.obj格式的3d模型。博客地址:https://blog.csdn.net/lady_killer9/article/details/89458246
wpf加载OBJ格式3d模型