lib3ds 2.0 和 opengl32 例子程序

转自http://blog.csdn.net/cheungmine/archive/2009/02/13/3888894.aspx

本例使用lib3ds库读取3ds文件,并使用opengl绘制。本例不使用贴图,仅仅展示lib3ds2.0的使用过程。这个例子是用lib3ds1.2.0的一个例子的翻版。lib3ds1.2.0已经找不到了。所以,我提供这个2.0版本的例子,以供学习之用。

    需要下载lib3ds2.0的包。编译成动态库。

    下面是例子的源代码player.c。只需要这一个文件。

 

 

  1. ///   
  2. // player.c   
  3. //   
  4. // 2009-2-13   
  5. //   
  6. // 作者:cheungmine   
  7. //   
  8. // 参考:   
  9. //   
  10. //        http://www.lib3ds.org/lib3ds-1.2.0/examples/player.c   
  11. //   
  12. // 目录结构:   
  13. //   
  14. // lib/lib3ds_2.0/src/   
  15. //          debug/lib3ds20d.lib  lib3ds20d.dll   
  16. //          release/lib3ds20.lib  lib3ds20.dll   
  17. //   
  18. // lib/lib3ds_2.0/   
  19. //          glut_test/player.c   
  20. //   
  21. // lib/win_opengl32/   
  22. //          inc/gl.h  glu.h   glut.h   
  23. //          lib/opengl32.lib  glu32.lib   glut32.lib   
  24. //          bin/opengl32.dll  glu32.dll   glut32.dll   
  25. //   
  26. ///   
  27. // 内存泄漏检测   
  28. // 在需要检测的地方放置语句:   
  29. //        _CrtDumpMemoryLeaks();   
  30. // 以下3句的次序不能改变   
  31. #define _CRTDBG_MAP_ALLOC      
  32. #include<stdlib.h>   
  33. #include<crtdbg.h>   
  34.   
  35. #include<stdio.h>   
  36. #include<string.h>   
  37. #include<math.h>   
  38. #include<assert.h>   
  39.   
  40. #include <windows.h>   
  41.   
  42. // 使用 USE_SGI_OPENGL 可能在某些机器上运行 wglMakeCurrent 系列函数返回失败的结果   
  43. #define GLUT_NO_LIB_PRAGMA   
  44.   
  45. // #define USE_SGI_OPENGL   
  46. #ifdef USE_SGI_OPENGL   
  47.     #include "../../sgi-opengl2-sdk/include/gl/gl.h"   
  48.     #include "../../sgi-opengl2-sdk/include/gl/glu.h"   
  49.     #include "../../sgi-opengl2-sdk/include/gl/glut.h"   
  50.   
  51.     #pragma comment(lib, "../../sgi-opengl2-sdk/lib/opengl.lib")   
  52.     #pragma comment(lib, "../../sgi-opengl2-sdk/lib/glu.lib")   
  53.     #pragma comment(lib, "../../sgi-opengl2-sdk/lib/glut.lib")   
  54. #else   
  55.     #include "../../win-opengl32/inc/GL.h"   
  56.     #include "../../win-opengl32/inc/GLU.h"   
  57.   
  58.     #pragma comment(lib, "../../win-opengl32/lib/OPENGL32.lib")   
  59.     #pragma comment(lib, "../../win-opengl32/lib/GLU32.lib")   
  60.   
  61.     #include "../../win-opengl32/inc/GLUT.h"   
  62.     #pragma comment(lib, "../../win-opengl32/lib/glut32.lib")   
  63. #endif   
  64.   
  65. //   
  66. // lib3ds   
  67. //   
  68. #include "../src/lib3ds.h"   
  69.   
  70. #ifdef _DEBUG   
  71. #  pragma comment(lib, "../src/debug/lib3ds20d.lib")   
  72. #else   
  73. #  pragma comment(lib, "../src/release/lib3ds20.lib")   
  74. #endif   
  75.   
  76. static const char* filename="E:/3DS/House/house.3ds";   
  77. static Lib3dsFile *model=0;   
  78.   
  79. static const char* camera=0;   
  80. static float current_frame=0.0;   
  81.   
  82. static int gl_width;   
  83. static int gl_height;   
  84.   
  85. static int camera_menu_id=0;   
  86. static int halt=0;   
  87.   
  88. #ifndef MAX   
  89. #  define MAX(x,y)  ((x)>(y)?(x):(y))   
  90. #endif   
  91.   
  92. static void camera_menu(int value)    
  93. {   
  94.     Lib3dsCamera *c;   
  95.     int i;   
  96.   
  97.     for( i=0; i<value; i++ ){   
  98.         if (i==model->ncameras)   
  99.             return;   
  100.         c = model->cameras[i];   
  101.     }   
  102.     if (c)   
  103.         camera=c->name;   
  104. }   
  105.   
  106. static void render_node(Lib3dsNode *node)   
  107. {   
  108.     Lib3dsNode      *p;   
  109.     Lib3dsMesh      *mesh;   
  110.     Lib3dsFace      *face;   
  111.     Lib3dsMaterial  *mat;   
  112.     Lib3dsMeshInstanceNode *meshData;   
  113.   
  114.     Lib3dsVector    *norm_verts;   
  115.     Lib3dsVector    *norm_faces;   
  116.        
  117.     int         i;   
  118.     unsigned    fi;   
  119.     float       M[4][4];   
  120.   
  121.     assert(model);   
  122.   
  123.     // 递归   
  124.     for (p=node->childs; p!=0; p=p->next){   
  125.         render_node(p);   
  126.     }   
  127.   
  128.     if (node->type==LIB3DS_NODE_MESH_INSTANCE)   
  129.     {   
  130.         if (strcmp(node->name,"$$$DUMMY")==0) {   
  131.             return;   
  132.         }   
  133.   
  134.         if (!node->user_id)    
  135.         {   
  136.             mesh = lib3ds_file_mesh_for_node(model, node);   
  137.             assert(mesh);   
  138.             if (!mesh) {   
  139.                 return;   
  140.             }   
  141.   
  142.             node->user_id = glGenLists(1);   
  143.             glNewList(node->user_id, GL_COMPILE);   
  144.                
  145.             norm_verts = (Lib3dsVector*) malloc(3*sizeof(Lib3dsVector)*mesh->nfaces);   
  146.             norm_faces = (Lib3dsVector*) malloc(sizeof(Lib3dsVector)*mesh->nfaces);                 
  147.   
  148.             lib3ds_matrix_copy(M, mesh->matrix);   
  149.             lib3ds_matrix_inv(M);   
  150.             glMultMatrixf(&M[0][0]);   
  151.                
  152.             lib3ds_mesh_calculate_face_normals(mesh, (float (*)[3])norm_faces);   
  153.             lib3ds_mesh_calculate_vertex_normals(mesh, (float (*)[3])norm_verts);   
  154.                
  155.             for (fi=0; fi<mesh->nfaces; ++fi) {   
  156.                 face = &(mesh->faces[fi]);   
  157.                 mat = 0;   
  158.                    
  159.                 if (face->material>=0 && face->material<model->nmaterials)   
  160.                     mat=model->materials[face->material];   
  161.                    
  162.                 if (mat)    
  163.                 {   
  164.                     static GLfloat a[4]={0,0,0,1};   
  165.                     float s;   
  166.                     glMaterialfv(GL_FRONT, GL_AMBIENT, a);   
  167.                     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);   
  168.                     glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);   
  169.                     s = pow(2, 10.0*mat->shininess);   
  170.                        
  171.                     if (s>128.0) {   
  172.                         s=128.0;   
  173.                     }   
  174.   
  175.                     glMaterialf(GL_FRONT, GL_SHININESS, s);   
  176.                 }   
  177.                 else {   
  178.                     float a[]={0.2, 0.2, 0.2, 1.0};   
  179.                     float d[]={0.8, 0.8, 0.8, 1.0};   
  180.                     float s[]={0.0, 0.0, 0.0, 1.0};   
  181.                     glMaterialfv(GL_FRONT, GL_AMBIENT, a);   
  182.                     glMaterialfv(GL_FRONT, GL_DIFFUSE, d);   
  183.                     glMaterialfv(GL_FRONT, GL_SPECULAR, s);   
  184.                 }   
  185.                    
  186.                 // Draw tri-face   
  187.                 glBegin(GL_TRIANGLES);   
  188.                    
  189.                 glNormal3fv(norm_faces[fi].v);  // face normal   
  190.   
  191.                 for (i=0; i<3; ++i) {   
  192.                     glNormal3fv(norm_verts[3*fi+i].v);  // vertex normal   
  193.                     glVertex3fv(mesh->vertices[face->index[i]]);   
  194.                 }   
  195.   
  196.                 glEnd();   
  197.             }   
  198.   
  199.             free(norm_faces);   
  200.             free(norm_verts);   
  201.                
  202.             glEndList();   
  203.         }   
  204.   
  205.         if (node->user_id) {   
  206.             glPushMatrix();   
  207.             meshData = (Lib3dsMeshInstanceNode*) node;   
  208.                
  209.             glMultMatrixf(&node->matrix[0][0]);   
  210.             glTranslatef(-meshData->pivot[0], -meshData->pivot[1], -meshData->pivot[2]);   
  211.             glCallList(node->user_id);   
  212.   
  213.             // glutSolidSphere(50.0, 20,20);   
  214.             glPopMatrix();   
  215.         }   
  216.     }   
  217. }   
  218.   
  219. static void display(void)   
  220. {   
  221.     int  i, li;   
  222.   
  223.     Lib3dsNode *nodC, *nodT, *nod;   
  224.     Lib3dsCameraNode *camNode;   
  225.     Lib3dsTargetNode *tgtNode;   
  226.     float             M[4][4];   
  227.        
  228.     GLfloat a[] = {0.0f, 0.0f, 0.0f, 1.0f};   
  229.     GLfloat c[] = {1.0f, 1.0f, 1.0f, 1.0f};   
  230.     GLfloat p[] = {0.0f, 0.0f, 0.0f, 1.0f};   
  231.        
  232.     Lib3dsLight *l;   
  233.   
  234.   
  235.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   
  236.   
  237.     if (!model) {   
  238.         return;   
  239.     }   
  240.   
  241.     nodC=lib3ds_file_node_by_name(model, camera, LIB3DS_NODE_CAMERA);   
  242.     nodT=lib3ds_file_node_by_name(model, camera, LIB3DS_NODE_CAMERA_TARGET);   
  243.        
  244.     if (!nodC || !nodT) {   
  245.         // 本测试程序要求必须存在 camera 和 target   
  246.         // 这里存在问题?以后的文章再处理不存在的情形   
  247.         assert(0 && "Camera or Target not found!");   
  248.         return;   
  249.     }   
  250.   
  251.     camNode = (Lib3dsCameraNode*) nodC;   
  252.     tgtNode = (Lib3dsTargetNode*) nodT;   
  253.   
  254.     glMatrixMode(GL_PROJECTION);   
  255.     glLoadIdentity();   
  256.     gluPerspective( camNode->fov, 1.0*gl_width/gl_height, 100.0, 20000.0);   
  257.     glMatrixMode(GL_MODELVIEW);   
  258.     glLoadIdentity();   
  259.     glRotatef(-90, 1.0, 0,0);   
  260.   
  261.     li=GL_LIGHT0;   
  262.            
  263.     for (i=0; i<model->nlights; i++)   
  264.     {   
  265.         l = model->lights[i];   
  266.         glEnable(li);   
  267.   
  268.         glLightfv(li, GL_AMBIENT, a);   
  269.         glLightfv(li, GL_DIFFUSE, c);   
  270.         glLightfv(li, GL_SPECULAR, c);  // p?   
  271.   
  272.         p[0] = l->position[0];   
  273.         p[1] = l->position[1];   
  274.         p[2] = l->position[2];   
  275.         glLightfv(li, GL_POSITION, p);   
  276.   
  277.         if (!l->spot_light) {   
  278.             continue;   
  279.         }   
  280.   
  281.         p[0] = l->target[0] - l->position[0];   
  282.         p[1] = l->target[1] - l->position[1];   
  283.         p[2] = l->target[2] - l->position[2];         
  284.            
  285.         glLightfv(li, GL_SPOT_DIRECTION, p);   
  286.            
  287.         ++li;   
  288.     }   
  289.   
  290.     lib3ds_matrix_camera(M, camNode->pos, tgtNode->pos, camNode->roll);   
  291.            
  292.     glMultMatrixf(&M[0][0]);   
  293.   
  294.     for (nod=model->nodes; nod!=0; nod=nod->next) {   
  295.         render_node(nod);   
  296.     }   
  297.        
  298.     if (!halt) {   
  299.         current_frame+=1.0;   
  300.            
  301.         if (current_frame>model->frames) {   
  302.             current_frame=0;   
  303.         }   
  304.   
  305.         lib3ds_file_eval(model, current_frame);   
  306.   
  307.         glutSwapBuffers();   
  308.         glutPostRedisplay();   
  309.     }   
  310. }   
  311.   
  312.   
  313. static void init(void)    
  314. {   
  315.     int    i;   
  316.   
  317.     glClearColor(0.5, 0.5, 0.5, 1.0);   
  318.     glShadeModel(GL_SMOOTH);   
  319.     glEnable(GL_LIGHTING);   
  320.     glEnable(GL_LIGHT0);   
  321.     glDisable(GL_LIGHT1);   
  322.     glDepthFunc(GL_LEQUAL);   
  323.     glEnable(GL_DEPTH_TEST);   
  324.     glEnable(GL_CULL_FACE);   
  325.     glCullFace(GL_BACK);   
  326.     //glDisable(GL_NORMALIZE);   
  327.     //glPolygonOffset(1.0, 2);   
  328.   
  329.     model=lib3ds_file_open(filename);   
  330.     if (!model) {   
  331.         printf("***ERROR*** Loading 3DS file failed.");   
  332.         exit(1);   
  333.     }   
  334.        
  335.     if (!model->cameras) {   
  336.         printf("***ERROR*** No Camera found.");   
  337.         lib3ds_file_free(model);   
  338.         model=0;   
  339.         exit(1);   
  340.     }   
  341.        
  342.     if (!camera) {   
  343.         camera = model->cameras[0]->name;   
  344.     }   
  345.   
  346.     camera_menu_id = glutCreateMenu(camera_menu);   
  347.   
  348.     for (i=0; i<model->ncameras; i++){   
  349.         glutAddMenuEntry(model->cameras[i]->name, i);   
  350.     }   
  351.   
  352.     glutAttachMenu(0);   
  353.   
  354.     lib3ds_file_eval(model, 0);   
  355. }   
  356.   
  357. static void reshape (int w, int h)   
  358. {   
  359.     gl_width=w;   
  360.     gl_height=h;   
  361.     glViewport(0,0,w,h);   
  362. }   
  363.   
  364. static void keyboard(unsigned char key, int x, int y)   
  365. {   
  366.     switch (key) {   
  367.     case 27:   
  368.         exit(0);   
  369.         break;   
  370.     case 'h':   
  371.         halt=!halt;   
  372.         glutPostRedisplay();   
  373.         break;   
  374.     }   
  375. }   
  376.   
  377. int main(int argc, char** argv)   
  378. {   
  379.     glutInit(&argc, argv);   
  380.   
  381.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);   
  382.     glutInitWindowSize(640, 480);    
  383.     glutInitWindowPosition(100, 100);   
  384.     glutCreateWindow(argv[0]);   
  385.   
  386.     init();   
  387.   
  388.     glutDisplayFunc(display);    
  389.     glutReshapeFunc(reshape);   
  390.     glutKeyboardFunc(keyboard);   
  391.     glutMainLoop();   
  392.   
  393.     /* Memory leaks detecting */  
  394.     _CrtDumpMemoryLeaks();   
  395.   
  396.     return(0);   
  397. }  

 

 

运行结果:

 

例子中使用的3ds23文件来自于:

http://www.sharecg.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值