你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:文章管理 / 本期精品文章
基于lib3ds和OpenGL的3ds文件的读取与显示
 

白改朝

摘要 详述使用lib3ds库和OpenGL来对3ds文件进行读取与显示,然后总结了一套读取显示3ds文件的方法。

关键词 OpenGLlib3ds,模型,贴图,材质,

 

3ds文件是3ds Max建模软件的标准输入输出格式,它的应用十分的广泛。各种虚拟现实项目都可使用它作为模型格式,甚至可以在游戏中使用,但是它的文件格式比较复杂而且没有相关的官方文档,所以对它的读取显示一直是一个问题。笔者通过多年的项目经验总结了一套操作3ds文件的方法,简单的说就是使用lib3ds库对3ds文件进行解析读取,然后利用OpenGL来显示。

 

一、模型的读取

 

要绘制模型必须首先将其读入内存。在我们读取3ds文件以前我们有必要了解一下3ds文件都包含那些组成部分。

1.         物体(Object

这可能是我们最关心的一部分了,一个3ds文件可以包含多个物体,一个物体可以是一座房屋、一头狮子、一个简单的长方体等等。物体又包含顶点数据、三角形索引数据、纹理坐标数据、材质列表数据等。每种数据由一个特定的ID标识,ID说明了跟在其后的是什么数据。

2.         材质

材质包含颜色、透明度、贴图文件名等数据。3ds文件里可以有多个材质,也可以没有。

3.         相机

相机数据中主要包含相机的位置、朝向等信息。

4.         灯光

灯光数据中主要包含灯光的位置、类型等信息。灯光可以是泛光灯、聚光灯等。

5.         关键帧

关键帧是用来描述动画的,其中包含了每个物体在每一关键帧处的变换矩阵。这样只要在绘制每一帧动画前给物体乘上相应的变换矩阵即可实现动画。需要注意一下3ds文件只能描述刚体动画,不能描述柔体动画。

读取的工作由lib3ds中的lib3ds_file_load(char *filename)函数来实现,lib3ds库将不同类型数据组织成以file为根节点的树状结构,而同类数据以链表的形式存放,可以像这样遍历一种数据:   

Lib3dsMesh *p;

for(p=file->meshes;p!=0;p=p->next)

{

   //在这里您可以用p做一些事情

}

以下为模型加载的关键代码:

// 加载模型

       file=lib3ds_file_load("投篮.3DS");

// 加载出错或找不到文件时显示错误信息并退出

       if (!file) {

              puts("没有找到文件\n");

              exit(1);

       }

以下代码获取模型文件的包围盒

       lib3ds_file_bounding_box_of_nodes(file, LIB3DS_TRUE, \

LIB3DS_FALSE, LIB3DS_FALSE, bmin, bmax);

       sx = bmax[0] - bmin[0];

       sy = bmax[1] - bmin[1];

       sz = bmax[2] - bmin[2];

       size = MAX(sx, sy); size = MAX(size, sz);

       cx = (bmin[0] + bmax[0])/2;

       cy = (bmin[1] + bmax[1])/2;

       cz = (bmin[2] + bmax[2])/2;

因为3ds Max制作的场景中可能没有灯光、相机所以人为的在模型的左右上下各加入一个,代码如下:

       if( !file->cameras ) {

              Lib3dsCamera *camera = lib3ds_camera_new("Camera_X");

              camera->target[0] = cx;

              camera->target[1] = cy;

              camera->target[2] = cz;

              memcpy(camera->position, camera->target, sizeof(camera->position));

              camera->position[0] = bmax[0] + 1.5 * MAX(sy,sz);

              camera->near_range = ( camera->position[0] - bmax[0] ) * .5;

              camera->far_range = ( camera->position[0] - bmin[0] ) * 2;

              lib3ds_file_insert_camera(file, camera);

 

              camera = lib3ds_camera_new("Camera_Y");

              camera->target[0] = cx;

              camera->target[1] = cy;

              camera->target[2] = cz;

              memcpy(camera->position, camera->target, sizeof(camera->position));

              camera->position[1] = bmin[1] - 1.5 * MAX(sx,sz);

              camera->near_range = ( bmin[1] - camera->position[1] ) * .5;

              camera->far_range = ( bmax[1] - camera->position[1] ) * 2;

              lib3ds_file_insert_camera(file, camera);

             

              camera = lib3ds_camera_new("Camera_Z");

              camera->target[0] = cx;

              camera->target[1] = cy;

              camera->target[2] = cz;

              memcpy(camera->position, camera->target, sizeof(camera->position));

              camera->position[2] = bmax[2] + 1.5 * MAX(sx,sy);

              camera->near_range = ( camera->position[2] - bmax[2] ) * .5;

              camera->far_range = ( camera->position[2] - bmin[2] ) * 2;

              lib3ds_file_insert_camera(file, camera);

             

              camera = lib3ds_camera_new("Camera_ISO");

              camera->target[0] = cx;

              camera->target[1] = cy;

              camera->target[2] = cz;

              memcpy(camera->position, camera->target, sizeof(camera->position));

              camera->position[0] = bmax[0] + .75 * size;

              camera->position[1] = bmin[1] - .75 * size;

              camera->position[2] = bmax[2] + .75 * size;

              camera->near_range = ( camera->position[0] - bmax[0] ) * .5;

              camera->far_range = ( camera->position[0] - bmin[0] ) * 3;

              lib3ds_file_insert_camera(file, camera);

       }

 

  推荐精品文章

·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 
·2023年7月目录
·2023年6月目录 
·2023年5月目录
·2023年4月目录 
·2023年3月目录 
·2023年2月目录 
·2023年1月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089