Qt实现读取显示obj文件——读取数据
来源:互联网 发布:mac版bt下载软件 编辑:程序博客网 时间:2024/04/30 16:25
前一篇写了关于实现的一些说明Qt实现读取显示obj文件——说明,这一篇说一说数据的读取~
说明
在头文件中我们建立一个OBJ文件的数据模型类;记录一些模型的结构与之后可能会使用的数据结构;(之后会在Github上上传所有的源码,但是数据不会上传~)
class _GLModel{public: QString path;//obj文件路径 QString mtllibName;//材质文件名称 size_t num_Vertices;//节点个数 size_t num_Normals;//节点向量的个数 size_t num_Textcoords;//节点纹理坐标个数 size_t num_Materials;//材质个数 size_t num_Faces;//面的个数 QList<Point3> list_Vertices;//节点对象集合 QList<VertNormals> list_Normals;//节点向量集合 QList<TextCoords> list_Textcoords;//纹理坐标集合 QList<Face> list_Faces;//面集合 QList<Material> list_Materials;//材质集合 QList<FacetNormal> list_FaceNormal;//面向量集合 QList<QString> list_ImagePath;//贴图路径集合,全路径 //GLfloat Center[3];//进行归一化之后的坐标中心 int textureArray[MAX_TEXTURE];//注册纹理数组};
读取OBJ数据结构
读取数据使用的是Qt中的类QInfo类,还是挺好用的~就是需要的注意的是每一行的结尾都会有\r\n回车换行符,和中文乱码,需要注意乱码和使用Trimmed()方法处理:
//读取OBJ文件_GLModel* _glReadOBJ(QString filename){ QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return NULL; } QString dirPath = _glGetDir(filename); QStringList list; QString currentMaterialName; _GLModel* model; model = new _GLModel(); QString split = ' '; model->path = filename; model->num_Faces = 0; model->num_Materials = 0; model->num_Normals = 0; model->num_Textcoords = 0; model->num_Vertices = 0; Point3 *v; TextCoords *vt; VertNormals *vn; Face *f; while (!file.atEnd()) { QByteArray line = file.readLine(); QString str(line); if (str.length() < 2)//太短~ continue; if (str[0] == 'm') { QStringList str0 = str.split(' '); QString mtlname = str0[1]; mtlname = mtlname.trimmed();//一定要trimmed处理,否则路径有问题 dirPath.append(mtlname); model->mtllibName = dirPath; _glReadMTL(model, model->mtllibName); } else if (str[0] == 'v'){ if (str[1] == 't'){//纹理 list = str.split(split);//无论是否包括Z方向的纹理都先取前两个值 vt = new TextCoords(); vt->U = list[_Y].toFloat(); vt->V = list[_Z].toFloat(); model->num_Textcoords++; model->list_Textcoords.push_back(*vt); } else if (str[1] == 'n'){//法向量 list = str.split(split); vn = new VertNormals(); vn->_NX = list[_Y].toFloat(); vn->_NY = list[_Z].toFloat(); vn->_NZ = list[_W].toFloat(); model->num_Normals++; model->list_Normals.push_back(*vn); } else//节点~ { list = str.split(split); v = new Point3(); v->_X = list[_Y].toFloat(); v->_Y = list[_Z].toFloat(); v->_Z = list[_W].toFloat(); model->num_Vertices++; model->list_Vertices.push_back(*v); } } else if (str[0] == 'u')//材质的名称 { list = str.split(split); currentMaterialName = list[1]; } else if (str[0] == 'f')//面 { str = str.trimmed(); list = str.split(split); f = new Face(); f->materialName = currentMaterialName; if (list[1].contains('/')) { for (int i = 1; i < list.length(); i++) { QStringList sublist = list[i].split('/'); f->list_index_Points.push_back(sublist[_X].toInt() - 1); f->list_index_TextCoords.push_back(sublist[_Y].toInt() - 1); if (list[1].split('/').length() == 3)//只有v和vt { f->list_index_VertNormals.push_back(sublist[_Z].toInt() - 1); } } } else//不包括/,那么只有节点 { for (int i = 1; i < list.length(); i++) { f->list_index_Points.push_back(list[i].toInt() - 1); } } model->num_Faces++; model->list_Faces.push_back(*f); } } return model;}
读取纹理文件
在读取OBJ的同时还读取了纹理文件mtl:
//读取mtl文件void _glReadMTL(_GLModel *model, QString fileName){ QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { qDebug("mtl文件打开失败。"); return; } QString dirPath; Material *material = NULL; QStringList list; int index = -1;//材质索引 QString split = ' '; while (!file.atEnd()) { QByteArray line = file.readLine(); if (line.length() == 2 && line.at(line.length() - 2) == '\r'&&line.at(line.length() - 1) == '\n')//如果读到了空行且材质指针不为空,那么证明当前的材质已经读完 { if (material&&material->materialName != NULL) model->list_Materials.push_back(*material); } QString str(line); if (str[0] == 'n')//名称 { list = str.split(split); material = new Material(); material->_Ka[_X] = 0.0; material->_Ka[_Y] = 0.0; material->_Ka[_Z] = 0.0; material->_Kd[_X] = 0.0; material->_Kd[_Y] = 0.0; material->_Kd[_Z] = 0.0; material->_Ks[_X] = 0.0; material->_Ks[_Y] = 0.0; material->_Ks[_Z] = 0.0; QString str1 = list[1]; material->materialName = str1.trimmed(); material->index_Material = ++index; model->num_Materials++; } else if (str[0] == 'm')//贴图路径 { list = str.split(split); dirPath = _glGetDir(fileName);//获取文件夹路径 dirPath.append(list[1].trimmed()); material->imageName = dirPath; model->list_ImagePath.push_back(dirPath); } else if (str[0] == 'K') { list = str.split(split); if (str[1] == 'a') { material->_Ka[0] = list[1].toFloat(); material->_Ka[1] = list[2].toFloat(); material->_Ka[2] = list[3].toFloat(); } else if (str[1] == 'd') { material->_Kd[0] = list[1].toFloat(); material->_Kd[1] = list[2].toFloat(); material->_Kd[2] = list[3].toFloat(); } else if (str[1] == 's') { material->_Ks[0] = list[1].toFloat(); material->_Ks[1] = list[2].toFloat(); material->_Ks[2] = list[3].toFloat(); } } }}
在实际的绘制obj中我虽然读取了材质参数,但是实际上并没有运用这些参数,主要用到了材质的纹理路径;我的意图主要还是渲染数据并贴上纹理~有兴趣的同学可以参考glm.c去自己实现,其实也很简单~
0 0
- Qt实现读取显示obj文件——读取数据
- Qt实现读取显示obj文件——绘制数据
- Qt实现读取显示obj文件——说明
- Qt实现读取显示obj文件——归一化坐标
- Qt实现读取显示obj文件——计算面的单位法向量
- Qt实现读取显示obj文件——创建并绑定纹理
- Qt实现读取显示obj文件——多线程加载纹理
- Qt实现读取显示obj文件——动态绑定纹理与消除纹理
- MATLAB读取和显示obj文件的数据
- Qt读取文件并显示
- obj-c 读取文件 。
- openGL读取obj文件
- vtk实战(十二)——读取.obj文件
- 读取并显示 obj (2)
- obj 文件读取 openGL 显示3D图
- QT快速读取显示SQLite3数据库数据
- C++读取OBJ文件中的数据(VS2013)
- obj-c读取文件方法
- 原生实现响应式模态框
- 【Linux】Centos之安装Nginx及注意事项
- oracle数据库创建用户并授权
- 查找主元素算法(java编写)
- CSDN日报20170316——《每个程序员都需要的中文排版指南》
- Qt实现读取显示obj文件——读取数据
- Android分包原理
- android应用开发-从设计到实现 3-1 原型设计
- struts2拦截器
- 计算机网络知识复习
- linux中使用openjdk配置java环境变量
- unix下压缩解压缩命令
- 什么是跨域?
- 随机森林