Chinaunix首页 | 论坛 | 博客
  • 博客访问: 495283
  • 博文数量: 135
  • 博客积分: 3010
  • 博客等级: 中校
  • 技术积分: 905
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-24 19:31
文章分类

全部博文(135)

文章存档

2010年(135)

我的朋友

分类: LINUX

2010-07-15 16:00:58

如何导出模型,请参考Maya部份。 现在我已经得到了一个非常简单易用的模型,下面就写一点代码把它加载到内存里,由于模型文件非常简单,所以加载非常简单,而且不浪费内存。 如果你是3DS Max用户,那么在 Power VR SDK 里已经带有相当强大的场景导出插件了,请参考相关文档及源码。

以下是头文件

 1  // 
 2  //  @ Project : MayaMELObjectExport
 3  //  @ File Name : play3dObj.h
 4  //  @ Date : 2007-2-23
 5  //  @ Author : kongfu.yang
 6  //  @ Company : 
 7  //  @ Copyright : 2007-2, Example source license. 
        By keep this header comment, 
        you may use this source file in your project for non-commicial or commicial purpose.
 8
 9  #ifndef _GL_ES_OBJ_H__
10  #define _GL_ES_OBJ_H__
11
12  #include "gles/gl.h"
13
14  struct play3dObjFixed
15  {
16      int faceCount;
17      int vertexCount;
18      GLfixed *vertexs;
19      GLfixed *normals;
20      GLfixed *uvs;
21      unsigned short *faces;
22
23      void loadFromFile(const char * fname);
24      play3dObjFixed() { vertexs = normals = uvs = 0; faces = 0; }
25      ~play3dObjFixed() { clean(); }
26      void clean(void);
27  };
28
29
30
31  #endif // _GL_ES_OBJ_H__

以下是实现:

 1  // 
 2  //  @ Project : MayaMELObjectExport
 3  //  @ File Name : play3dObj.h
 4  //  @ Date : 2007-2-23
 5  //  @ Author : kongfu.yang
 6  //  @ Company : 
 7  //  @ Copyright : 2007-2, Example source license. 
          By keep this header comment, 
          you may use this source file in your project for non-commicial or commicial purpose.
 8
 9  #include "play3dObj.h"
10  #include 
11  #include 
12
13  void play3dObjFixed::loadFromFile(const char * fname)
14  {
15      FILE * fp = fopen(fname, "rb");
16      fread( &faceCount, sizeof(int), 1, fp );
17      fread( &vertexCount, sizeof(int), 1, fp );
18
19      vertexs = (GLfixed *) malloc( sizeof(GLfixed) * vertexCount * 3 );
20      normals = (GLfixed *) malloc( sizeof(GLfixed) * vertexCount * 3 );
21      uvs = (GLfixed *) malloc( sizeof(GLfixed) * vertexCount * 2 );
22      faces = (unsigned short *) malloc( sizeof(unsigned short) * faceCount * 3 );
23
24      fread( vertexs, sizeof(GLfixed), vertexCount * 3, fp );
25      fread( normals, sizeof(GLfixed), vertexCount * 3, fp );
26      fread( uvs,     sizeof(GLfixed), vertexCount * 2, fp );
27
28      fread( faces,   sizeof(unsigned short), faceCount * 3, fp );
29
30      fclose(fp);
31  }
32
33  void play3dObjFixed::clean(void)
34  {
35      if ( vertexs != 0 ) free(vertexs);
36      if ( normals != 0 ) free(normals);
37      if ( uvs != 0 ) free(uvs);
38      if ( faces != 0 ) free(faces);
39      vertexs = normals = uvs = 0; faces = 0;
40  }

在适当的位置创建play3dObjFixed g_model并调用其loadFromFile()方法就不罗嗦了。

以下是绘制:

万分抱歉,2007-3-1之前这部份代码的53行少了"* 3",如果你直接拷过去使用的话,会发现只能显示模型的1/3的面。这是因为我先后在家里的两台电脑上改过这个程序,编写本文的台式机上的是比较老的版 本,今天在做另一个例子时才发现。看来,再简单的程序,也需要用CVS来管理呀。

 37  void draw(HWND hWnd, HDC hdc)
 38  {
 39      if ( ! g_egl.isInitialized() ) return;
 40
 41      if ( g_egl.makeCurrent() )
 42      {
 43          glClear(GL_COLOR_BUFFER_BIT);
 44
 45          glEnableClientState( GL_VERTEX_ARRAY );
 46          glEnableClientState( GL_NORMAL_ARRAY );
 47          // glEnableClientState( GL_UV_ARRAY );
 48          // 3 means (x,y,z) for one vertex, coord is in fixed number, stride is 0
 49          glVertexPointer( 3, GL_FIXED, 0, g_model.vertexs ); 
 50          glNormalPointer( GL_FIXED, 0, g_model.normals );
 51          // glTexCoordPointer( 3, GL_FIXED, 0, g_model.uvs );
 52
 53          glDrawElements( GL_TRIANGLES, g_model.faceCount * 3, GL_UNSIGNED_SHORT, g_model.faces );
 54
 55          g_egl.swapBuffers();
 56      }
 57
 58      reportError();
 59  }

这里有三组重要的API:glEnableClientState,glVertexPointer,glDrawElements。

glEnableClientState是指示OpenGL状态机打开对Vertex/Normal/UV Array的支持,使得批量发送模型数据成为可能。

glVertexPointer,glNormalPointer, glTexCoordPoint等Pointer则是实际用来发送模型数据的。

glDrawElements, glDrawArray则是用利用已发送数据来绘制实际图形的,前者通过额外的顶点索引数组来定义面,后者直接利用已经发送的模型数据数组绘制(在HelloEGL 例子里用的就是它),前者显然更加灵活。glDrawElements第一个参数决定绘制的图元,不过OpenGL ES 1.x最多画三角形,四边形和多边形是不支持滴;第二个参数是索引元素的个数,不是面的个数;第三个参数是顶点索引的数据类型,注意OpenGL ES 1.x不支持int/unsigned int;最后是实际的数据。

当前OpenGL ES的书籍并不多,好在OpenGL ES对OpenGL删得多改得少,完全可以把OpenGL的书籍拿来参考。以上API除了使用定点数之外,其它与OpenGL规范中的同名API用法完全 相同,搞一本OpenGL参考手册(Blue Book)到手边是 非常有必要的。

绘制效果:

PC Emulator Dell Axim X51v Device
draw flyship model in triangle faces on pc emulator draw flyship model in triangle faces on x51v device

阅读(1375) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~