OpenGL ES系列 之 提高-1:加载模型
来源:互联网 发布:MacBook安装Mac不用u盘 编辑:程序博客网 时间:2024/06/06 07:16
如何导出模型,请参考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 : http://www.play3d.net 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__1112 #include "gles/gl.h"1314 struct play3dObjFixed15 {16 int faceCount;17 int vertexCount;18 GLfixed *vertexs;19 GLfixed *normals;20 GLfixed *uvs;21 unsigned short *faces;2223 void loadFromFile(const char * fname);24 play3dObjFixed() { vertexs = normals = uvs = 0; faces = 0; }25 ~play3dObjFixed() { clean(); }26 void clean(void);27 };28293031 #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 : http://www.play3d.net 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 <stdio.h>11 #include <stdlib.h>1213 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 );1819 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 );2324 fread( vertexs, sizeof(GLfixed), vertexCount * 3, fp );25 fread( normals, sizeof(GLfixed), vertexCount * 3, fp );26 fread( uvs, sizeof(GLfixed), vertexCount * 2, fp );2728 fread( faces, sizeof(unsigned short), faceCount * 3, fp );2930 fclose(fp);31 }3233 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- OpenGL ES系列 之 提高-1:加载模型
- OpenGL ES系列 之 提高-3:光照
- OpenGL ES系列 之 应用 - 1:Wavefront .obj加载
- OpenGL ES系列 之 提高-2:材质纹理
- OpenGL ES系列之提高-2:材质纹理
- OpenGL ES 加载3D模型
- OpenGL ES系列 之 基本-0:了解OpenGL ES社区
- OpenGL ES系列 之 基本-1:初始化EGL
- OpenGL ES系列 之 基本-1:初始化EGL
- OpenGL ES系列 之 深入 - 1:压缩纹理
- OpenGL ES系列之基本-1:初始化 EGL
- OpenGL ES系列 之 基本-1:初始化EGL
- OpenGL ES 模型视图之缩放操作
- OpenGL ES 模型视图之平移操作
- OPENGL ES 从零开始系列
- opengl es 渲染方式与 纹理坐标设定 ,OpenGL ES 模型视图之缩放操作
- OpenGL ES系列 之 预备-1:开发Windows Mobile 5.0 应用程序
- Android开发 之 OpenGL ES系列(1--创建显示环境)
- H264的学习参考(转)
- oracle学习之日期函数
- 求职:C++软件开发/Symbian开发
- JavaDoc命令使用说明
- forward和sendRedirect的区别
- OpenGL ES系列 之 提高-1:加载模型
- Windows Mobile手机软件安装卸载方法
- 程序员面试题精选100题(14)-圆圈中最后剩下的数字
- 汉字转换拼音开源项目
- 程序员面试题精选100题(15)-含有指针成员的类的拷贝
- oracle数据库性能监控的SQL的几种情况
- MISRA C指导指南解读系列7(MISRA C规则68-86)
- 程序员面试题精选100题(16)-O(logn)求Fibonacci数列
- 软浮点 高版本交叉编译器制作