基于OpenGLES的地球仪案例分析成品.docx
- 文档编号:6288760
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:14
- 大小:1.18MB
基于OpenGLES的地球仪案例分析成品.docx
《基于OpenGLES的地球仪案例分析成品.docx》由会员分享,可在线阅读,更多相关《基于OpenGLES的地球仪案例分析成品.docx(14页珍藏版)》请在冰豆网上搜索。
基于OpenGLES的地球仪案例分析成品
成绩
评卷人
姓名
刘元涛
学号
2013112902
华中师范大学
研究生课程论文
论文题目:
基于OpenGLES开发的地球仪在移动学习中的应用
完成时间:
2014-6-16
课程名称:
计算机图形学
专业:
教育技术学
年级:
2013级
目录
基于OpenGLES开发的地球仪在移动学习中的应用1
1程序说明1
1.1模型说明1
1.2绘制球体2
1.3纹理3
1.4交互6
2基于OpenGLES开发的地球仪的功能展示8
2.1触控操作球体的大小8
2.2触摸来操作球体的旋转9
3基于OpenGLES开发的地球仪在教育中的意义10
3.1地球仪在地里教学中的意义10
3.2移动学习10
3.3基于移动学习的地球仪在教学中的意义11
基于OpenGLES开发的地球仪在移动学习中的应用
1程序说明
1.1模型说明
1)OpenGLES绘制三角形拼成球体
2)2的幂次方大小的图片作为纹理映射到整个球面上
3)触控缩放球体
4)拖动旋转球体
程序界面如图1-1所示:
图1-1
1.2绘制球体
1)将球体横着切成N层,然后按弧线竖着切M份,就得到了N*M个长方形。
2)在按对角戏切分就得到了2*N*M个三角形,如图1-2所示。
3)然后计算每个三角形的顶点坐标
绘制三角形(面)的函数:
//为画笔指定顶点坐标数据
gl.glVertexPointer(3,GL10.GL_FIXED,0,mVertexBuffer);
//按三角形模式(vCount个点中,每三个点作为一组)绘制多个三角形
gl.glDrawArrays(GL10.GL_TRIANGLES,0,vCount);
OpenGLES绘制物体的面都是由三角形组成,所以我们绘制球体,就是要将球面分成很多三角形,三角形越多,我们的球面就越光滑。
首先我们沿着维度方向将球体进行切分,接着沿着经度方向将球体进行切分,经纬度切割线相交后的点就是我们的顶点,有了顶点我们就可以进行绘制了,如图1-3所示。
图1-2
图1-3
introw=(180/angleSpan)+1;//球面切分的行数
intcol=360/angleSpan;//球面切分的列数
我们用for循环创建模型,将在纹理进行解释。
1.3纹理
因为纹理是以S,T方向标示的,就像x,y方向,如图1-4所示:
图1-4
S方向对应纬度切割线,T方向对应经度切割线。
S方向上维度切割线的周长和矩形的长对应。
由此推断,南北极就压缩一个点,而赤道是和原图一样的,而赤道和极点间的图像都进行对应的压缩。
最后把图像均匀的附在球面上,如图1-5所示。
图1-5
纹理的图一定是2的幂次方,这样才能进行贴图。
publicintinitTexture(GL10gl,intresourceId){
int[]textures=newint[1];
gl.glGenTextures(1,textures,0);
intcurrTextureId=textures[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D,currTextureId);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
InputStreamis=this.getResources().openRawResource(resourceId);
BitmapbitmapTmp;
try{
bitmapTmp=BitmapFactory.decodeStream(is);
}finally{
try{
is.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
//bitmap和纹理绑定
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bitmapTmp,0);
bitmapTmp.recycle();
returncurrTextureId;
}
计算每个三角形的坐标与其对应这张二维纹理图的坐标
//顶点的数量为坐标值数量的1/3,因为一个顶点有3个坐标
vCount=alVertix.size()/3;
//将alVertix中的坐标值转存到一个int数组中
intvertices[]=newint[vCount*3];
for(inti=0;i vertices[i]=alVertix.get(i); } alVertix.clear(); //纹理 ArrayList intcol=360/angleSpan;//球面切分的列数 floatsplitRow=row; floatsplitCol=col; for(inti=0;i { if(i>0&&i for(intj=0;j //中间行的两个相邻点与下一行的对应点构成三角形 intk=i*col+j; //第1个三角形顶点 alVertix.add(vertices[(k+col)*3]); alVertix.add(vertices[(k+col)*3+1]); alVertix.add(vertices[(k+col)*3+2]); //纹理坐标 alTexture.add(j/splitCol); alTexture.add((i+1)/splitRow); //第2个三角形顶点 inttmp=k+1; if(j==col-1){ tmp=(i)*col; } alVertix.add(vertices[(tmp)*3]); alVertix.add(vertices[(tmp)*3+1]); alVertix.add(vertices[(tmp)*3+2]); //纹理坐标 alTexture.add((j+1)/splitCol); alTexture.add(i/splitRow); //第3个三角形顶点 alVertix.add(vertices[k*3]); alVertix.add(vertices[k*3+1]); alVertix.add(vertices[k*3+2]); //纹理坐标 alTexture.add(j/splitCol); alTexture.add(i/splitRow); } for(intj=0;j //中间行的两个相邻点与上一行的对应点构成三角形 intk=i*col+j; //第1个三角形顶点 alVertix.add(vertices[(k-col)*3]); alVertix.add(vertices[(k-col)*3+1]); alVertix.add(vertices[(k-col)*3+2]); alTexture.add(j/40f); alTexture.add((i-1)/splitRow); inttmp=k-1; if(j==0){ tmp=i*col+col-1; } //第2个三角形顶点 alVertix.add(vertices[(tmp)*3]); alVertix.add(vertices[(tmp)*3+1]); alVertix.add(vertices[(tmp)*3+2]); alTexture.add((j-1)/splitCol); alTexture.add(i/splitRow); //第3个三角形顶点 alVertix.add(vertices[k*3]); alVertix.add(vertices[k*3+1]); alVertix.add(vertices[k*3+2]); alTexture.add(j/splitCol); alTexture.add(i/splitRow); } } } //顶点的数量为坐标值数量的1/3,因为一个顶点有3个坐标 vCount=alVertix.size()/3; //将alVertix中的坐标值转存到一个int数组中 vertices=newint[vCount*3]; for(inti=0;i vertices[i]=alVertix.get(i); } //创建绘制顶点数据缓冲 ByteBuffervbb=ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//设置字节顺序 mVertexBuffer=vbb.asIntBuffer();//转换为int型缓冲 mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mVertexBuffer.position(0);//设置缓冲区起始位置 //创建顶点法向量数据缓冲 ByteBuffernbb=ByteBuffer.allocateDirect(vertices.length*4); nbb.order(ByteOrder.nativeOrder());//设置字节顺序 mNormalBuffer=vbb.asIntBuffer();//转换为int型缓冲 mNormalBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mNormalBuffer.position(0);//设置缓冲区起始位置 //创建纹理坐标缓冲 floattextureCoors[]=newfloat[alTexture.size()];//顶点纹理值数组 for(inti=0;i textureCoors[i]=alTexture.get(i); } ByteBuffercbb=ByteBuffer.allocateDirect(textureCoors.length*4); cbb.order(ByteOrder.nativeOrder());//设置字节顺序 mTextureBuffer=cbb.asFloatBuffer();//转换为int型缓冲 mTextureBuffer.put(textureCoors);//向缓冲区中放入顶点着色数据 mTextureBuffer.position(0);//设置缓冲区起始位置 1.4交互 给ball实体设置三个旋转变量: publicfloatmAngleX=0;//沿x轴旋转角度 publicfloatmAngleY=0;//沿y轴旋转角度 publicfloatmAngleZ=0;//沿z轴旋转角度 给ball实体设置缩放变量: publicfloatzoom=-3f; publicfinalfloatmaxZoom=-2f; publicfinalfloatminZoom=-4f; ball每次draw之前变换坐标系: gl.glTranslatef(0f,0f,zoom); gl.glRotatef(mAngleX,y_axis[0],y_axis[1],y_axis[2]); 重写OnTouch函数 privateOnTouchListeneronTouchListener=newOnTouchListener(){ floatlastX,lastY; privateintmode=0;//触控点的个数 floatoldDist=0; @Override publicbooleanonTouch(Viewv,MotionEventevent){ switch(event.getAction()&MotionEvent.ACTION_MASK){ caseMotionEvent.ACTION_DOWN: mode=1; lastX=event.getRawX(); lastY=event.getRawY(); break; caseMotionEvent.ACTION_POINTER_DOWN: mode+=1; oldDist=caluDist(event); break; caseMotionEvent.ACTION_POINTER_UP: mode-=1; break; caseMotionEvent.ACTION_UP: mode=0; break; caseMotionEvent.ACTION_MOVE: if(mode>=2){ floatnewDist=caluDist(event); if(Math.abs(newDist-oldDist)>2f){ zoom(newDist,oldDist); } }else{ floatdx=event.getRawX()-lastX; floatdy=event.getRawY()-lastY; floata=180.0f/320; ball.mAngleX+=dx*a; ball.mAngleY+=dy*a; } break; } lastX=(int)event.getRawX(); lastY=(int)event.getRawY(); returntrue; } }; 2基于OpenGLES开发的地球仪的功能展示 2.1触控操作球体的大小 通过手势的触控,程序通过记录mode是用来记录当前屏幕上按下了几个点,一次来控制球体是否缩放。 通过整体的缩放,操作者可以查看球体的整体和局部图,如图2-1所示。 图2-1 2.2触摸来操作球体的旋转 操作者可以通过触摸屏幕来操作球体的旋转,球体的旋转方向和手势的触摸方向一致,通过球体的旋转来查找各大洲、大洋在地球中的位置,还可以通过手势操作模拟地球的旋转,如图2-2所示. 图2-2 3基于OpenGLES开发的地球仪在教育中的意义 3.1地球仪在地里教学中的意义 地球仪的作用: 认识大洲,大洋及世界地形: 在地球仪上,人们用不同的颜色、符号和文字来表示陆地、海洋、山脉、河湖、国家和城市等地理事物的位置、形状及名称等。 地球仪演示解释地球自转,公转,昼夜更替和四季的变化 3.2移动学习 移动学习(Mobilelearning,缩写为M-Learning),是一种在移动计算设备帮助下的能够在任何时间、任何地点发生的学习,移动学习所使用的移动计算设备必须能够有效地呈现学习内容并且提供教师与学习者之间的双向交流。 它是一种跨越地域限制,充分利用可携技术的学习方式。 移动学习的特点决定了移动学习和传统教育相比具有独特的优势,主要表现在: 第一、可以随时随地的学习。 学习者能在任何地点、任何时间、以任何方式学习任何内容,这种独特优势是其他学习方式所望尘莫及的,极大地满足了"总在线"的学习需求,这也奠定了移动学习在未来学习中的重要地位。 第二、可以充分利用琐碎的时间学习。 移动学习以其独有学习的碎片性的特点,为学习者提供了学习知识的便利,使学习者可以充分利用琐碎的时间,掌握一个相对完整的知识组块,正如面对一堆看似杂乱无章知识碎片,经过每天一片、一点的摄入和积累,最终会形成一个完成的知识拼图一样。 第三、满足了个性化的学习需求。 移动学习的交互性可以实现信息及时的双向流通,有利于培养学习者的交流沟通能力,激发学习者的学习热情,发展学习者的个性,有利于提高学习者的学习成绩和信心。 第四,可以消除心理负担。 从心理学角度看,对于一些性格内向,害羞等性格的学习者来说,移动学习能够弥补传统课堂和面对面学习中遇到的一些尴尬的场面,驱除交流的胆怯心理,从而轻松的学习和交流,等等。 3.3基于移动学习的地球仪在教学中的意义 移动学习在近些年已经成为了E-Learning的研究热点。 作为一种的新的教育技术,移动学习将在未来的教与学中发挥更大作用。 本文主要是介绍了基于OpenGLES开发的地球仪,能够有效的辅助学生在地里知识中关于地球的地貌和地球的运转的学习,其在移动学习中有着很大的开发价值和应用空间。 基于OpenGLES开发的地球仪除了具有实体地球仪的诸多优点外,还具有实体地球仪不具有的一些优点,主要包括: 第一,寓教于乐。 基于OpenGLES开发的地球仪采用在移动终端运行的形式,老师在讲台通过大屏幕在PC端进行展示,学生可以在下面通过在移动终端的触摸、滑动等手势来控制自己的地球仪。 学生通过触摸、滑动等操作,对地球有一定的认识,从而对基于移动端的学习产生兴趣。 这样学习者从被动的接受教育者转变成主动的学习者,每位学生。 基于OpenGLES开发的地球仪,将每个学生都转变成为了“潜在”的、具各自主学习能力的学习者,使学生可以在休闲娱乐的同时掌握地理知识。 第二,碎片化学习。 基于OpenGLES开发的地球仪采用在移动终端运行的形式,学生不仅在课堂可以与老师互动操作地球仪,还可以在课后一些零碎时间进行地理知识的学习。 同时还可以配套的增加一些关于地球仪的操作提示,使学习者在操作地球仪的时候与移动设备产生互动,加深记忆。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于OpenGL ES的地球仪案例分析成品 基于 OpenGL ES 地球仪 案例 分析 成品
![提示](https://static.bdocx.com/images/bang_tan.gif)