鲲鹏it教育android课件游戏开发项目_第1页
鲲鹏it教育android课件游戏开发项目_第2页
鲲鹏it教育android课件游戏开发项目_第3页
鲲鹏it教育android课件游戏开发项目_第4页
鲲鹏it教育android课件游戏开发项目_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android游戏开发OpenGL开发基础框架绘制立体图形课程安排三角形的顶点法和索引法渲染流水线福特怎样组装汽车?流水线是将一个重复的过程分为若干个子过程,每个子过程可以和其他子过程并行运作。渲染流水线与此类似,只是图形渲染替代了汽车生产。实质上是图形芯片内部处理图形信号相互独立的并行处理单元。图形数据(顶点,点段,三角面)从流水线的开端输入经过流水线的各个阶段图元处理:计算顶点坐标和颜色顶点缓冲:将顶点数据放入内存或显存,使用java.nio变换与光照:变换包括视口变换、投影变换、模型变换等。根据光源、材质、位置等信息计算出光照情况。图元装配:所有图形基础数据进行组装光栅化:对三维空间进行拍照,使之成为二维像素集合雾化:处理模糊、锐化、烟等特效Alpha测试:当Alpha值满足某特定条件时才会被渲染出来。如设置glAlphaFunc(GL_EQUAL,0.0f)是只显示Alpha=0(完全不透明)的区域,透明区域将被删除。GL_ALWAYS、GL_EQUAL、GL_NEVER、GL_GEQUAL、GL_LESS、GL_NOTEQUAL、GL_LEQUAL深度测试:检测Z值。模板测试:根据三角面上的显示标记进行特殊处理。这些标记称为模板缓冲区。颜色混合:将三角面的颜色与设定颜色进行混合。图像抖动:是一种在可用颜色数量较少的系统中,使用的利用人眼色差产生丰富颜色的技巧。初始化OpenGLESGLInitActivity:程序主入口GLRender:渲染场景MySurfaceView:获取用户输入,实现人机交互。publicclassGLInitActivityextendsActivity{@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);

MySurfaceViewmySurfaceView=newMySurfaceView(this);

setContentView(mySurfaceView);}}初始化OpenGLES要先创建一个GLRenderer对象,然后在构成中调用sendRenderer()设置渲染对象。重写onTouchEvent获取用户的触控输入。publicclassMySurfaceViewextendsGLSurfaceView{privatefinalfloatTOUCH_SCALE_FACOTOR=180.0f/320;privateGLRender_render=newGLRender();privatefloat_preX=0.0f;privatefloat_preY=0.0f;publicMySurfaceView(Contextcontext){super(context);this.setRenderer(_render);}@OverridepublicbooleanonTouchEvent(MotionEventevent){floatx=event.getX();floaty=event.getY();switch(event.getAction()){caseMotionEvent.ACTION_MOVE:floatdx=x-_preX;floatdy=y-_preY;_render.zrot+=dx*TOUCH_SCALE_FACOTOR;_render.xrot+=dy*TOUCH_SCALE_FACOTOR;this.requestRender();}_preX=x;_preY=y;returntrue;}初始化OpenGLESGLRenderer负责场景渲染,有三个比较重要的方法:onSurfaceCreated(),onDrawFrame()和onSurfaceChanged()方法。onSurfaceCreated():场景创建时的操作,例如图形数据的创建,光照对象的设置。onDrawFrame()用于场景绘制时的操作,例如变换,实现动画。onSurfaceChanged()用于屏幕发生变化时的操作,例如屏幕旋转、视口发生变化。publicclassGLRenderimplementsRenderer{floatxrot,yrot,zrot;publicvoidonSurfaceCreated(GL10gl,EGLConfigconfig){//黑色背景//gl.glClearColor(0,0,0,0);//蓝色背景//gl.glClearColor(0,0,1.0f,0);//红色背景gl.glClearColor(1.0f,0,0,0);//启用阴影平滑gl.glShadeModel(GL10.GL_SMOOTH);//启用深度测试gl.glEnable(GL10.GL_DEPTH_TEST);//清除深度缓冲数据gl.glClearDepthf(1.0f);//深度测试的类型gl.glDepthFunc(GL10.GL_LEQUAL);//精细的透视修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_NICEST);}publicvoidonDrawFrame(GL10gl){//清除屏幕和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);//重置当前的模型观察矩阵gl.glLoadIdentity();}publicvoidonSurfaceChanged(GL10gl,intwidth,intheight){floatratio=(float)width/height;//设置OpenGL视口gl.glViewport(0,0,width,height);//设置透视投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);//单位化投影矩阵gl.glLoadIdentity();//设置视口的大小gl.glFrustumf(-ratio,ratio,-1,1,1,10);//选择模型观察矩阵gl.glMatrixMode(GL10.GL_MODELVIEW);//单位化观察矩阵gl.glLoadIdentity();}解释glShadeModel函数用于控制opengl中绘制指定两点间其他点颜色的过渡模式。参数一般为GL_SMOOTH(默认),GL_FLAT。opengl默认是将制定的两点颜色进行插值,绘制之间的其他点。如果两点的颜色相同,使用两个参数效果相同。如果两点颜色不同,GL_SMOOTH会出现过渡效果,GL_FLAT则只是以指定的某一点的单一色绘制其他所有点。当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。在Android系统中,使用OpenGLES的作用是构建三维效果。在OpenGLES中,三维效果都是通过构建三角形实现的。在OpenGL中有两个比较重要的投影变换函数,glViewport和glOrtho。glOrtho是创建一个正交平行的视景体。一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。而作为它的对立情况,glFrustum则产生一个透视投影。这是一种模拟真是生活中,人们视野观测物体的真实情况。例如:观察两条平行的火车到,在过了很远之后,这两条铁轨是会相交于一处的。还有,离眼睛近的物体看起来大一些,远的物体看起来小一些。glOrtho(left,right,bottom,top,near,far),left表示视景体左面的坐标,right表示右面的坐标,bottom表示下面的,top表示上面的。这个函数简单理解起来,就是一个物体摆在那里,你怎么去截取他。这里,我们先抛开glViewport函数不看。先单独理解glOrtho的功能。假设有一个球体,半径为1,圆心在(0,0,0),那么,我们设定glOrtho(-1.5,1.5,-1.5,1.5,-10,10);就表示用一个宽高都是3的框框把这个球体整个都装了进来。如果设定glOrtho(0.0,1.5,-1.5,1.5,-10,10);就表示用一个宽是1.5,高是3的框框把整个球体的右面装进来;如果设定glOrtho(0.0,1.5,0.0,1.5,-10,10);就表示用一个宽和高都是1.5的框框把球体的右上角装了进来。上述三种情况可以见图:glOrtho函数只是负责使用什么样的视景体来截取图像,并不负责使用某种规则把图像呈现在屏幕上。glViewport主要完成这样的功能。它负责把视景体截取的图像按照怎样的高和宽显示到屏幕上。缓冲变换//获取整形缓冲数据publicIntBuffergetIntBuffer(int[]vertexes){IntBufferbuffer;ByteBufferqbb=ByteBuffer.allocateDirect(vertexes.length*4);qbb.order(ByteOrder.nativeOrder());

buffer=qbb.asIntBuffer();buffer.put(vertexes);buffer.position(0);returnbuffer;}//获取字节型缓冲数据publicByteBuffergetByteBuffer(byte[]vertexes){ByteBufferbuffer=null;buffer=ByteBuffer.allocateDirect(vertexes.length);buffer.put(vertexes);buffer.position(0);returnbuffer;}顶点法绘制三角形OpenGLES向我们提供了两种绘制三角面的方法,一种是顶点法,一种是索引法。现在要画一个简单的矩形面。我们首先需要向OpenGLES的绘制流水线指定一个顶点缓冲,缓冲中记录了各个顶点的坐标数据,渲染的时候OpenGLES将会从缓冲中依次读取各个顶点的数据并且依次连接填充为三角面。例如构成一个简单的矩形平面我们至少需要两个三角面。需要六组顶点数据。第一步,需要在GLRender类中定义FloatBuffer顶点缓冲。私有全局变量。第二步,需要在OnSurfaceCreated中创建图形数据,定义一个vertexs坐标数组。调用getFloatBuffer()方法将vertexts数据写入顶点缓冲。//定义顶点缓冲privateFloatBuffer_vertexsBuffer;//第2个三角

vertexs[9]=1.0f;vertexs[10]=1.0f;vertexs[11]=0.0f;vertexs[12]=-1.0f;vertexs[13]=-1.0f;vertexs[14]=0.0f;vertexs[15]=1.0f;vertexs[16]=-1.0f;vertexs[17]=0.0f;//创建顶点缓冲

this._vertexsBuffer=Util.getFloatBuffer(vertexs);//告诉系统对透视进行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);//定义顶点数据

floatvertexs[]=newfloat[18];//第1个三角

vertexs[0]=1.0f;vertexs[1]=1.0f;vertexs[2]=0.0f;vertexs[3]=-1.0f;vertexs[4]=1.0f;vertexs[5]=0.0f;vertexs[6]=-1.0f;vertexs[7]=-1.0f;vertexs[8]=0.0f;顶点法绘制三角形第三步,需要在OnDrawFrame()方法中实现对两个三角面的渲染绘制。需要调用glVertextPointer()为绘制流水线指定顶点缓冲。调用glDrawArrays()告诉OpenGLES绘制流水线用顶点法。调用glDisableClientState()关闭顶点缓冲。

//移入屏幕一段距离

gl.glTranslatef(0.0f,0.0f,-3.0f);

//设置3个方向的旋转gl.glRotatef(xrot,1.0f,0.0f,0.0f);gl.glRotatef(yrot,0.0f,1.0f,0.0f);gl.glRotatef(zrot,0.0f,0.0f,1.0f);//允许设置顶点gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

gl.glVertexPointer(3,GL10.GL_FLOAT,0,this._vertexsBuffer);gl.glDrawArrays(GL10.GL_TRIANGLES,0,6);//取消顶点设置

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//结束绘制

gl.glFinish();索引法绘制三角形索引法仍然是用GL_TRIANGLES绘制三角面。相比顶点法我们只需要四组的顶点数据,还需要指定一个索引缓冲,索引缓冲描述了顶点绘制的序列。第一步,定义FloatBuffer顶点缓冲和ByteBuffer索引缓冲。第二步,定义长度12的顶点数组,创建byte数组,代表v0-v1-v2和v0-v2-v3,因此数组长度为6。调用getFloatBuffer()和getByteBuffer()//定义顶点缓冲privateFloatBuffer_vertexsBuffer;//定义索引缓冲privateByteBuffer_indicesBuffer;vertexs[9]=1.0f;vertexs[10]=-1.0f;vertexs[11]=0.0f;//创建索引数据

byteindices[]=newbyte[6];

indices[0]=0;indices[1]=1;indices[2]=2;indices[3]=0;indices[4]=2;indices[5]=3;

//创建顶点缓冲

this._vertexsBuffer=Util.getFloatBuffer(vertexs);

//创建索引缓冲

this._indicesBuffer=Util.getByteBuffer(indices);//创建顶点数据

floatvertexs[]=newfloat[12];

vertexs[0]=1.0f;vertexs[1]=1.0f;vertexs[2]=0.0f;

vertexs[3]=-1.0f;vertexs[4]=1.0f;vertexs[5]=0.0f;

vertexs[6]=-1.0f;vertexs[7]=-1.0f;vertexs[8]=0.0f;

索引法绘制三角形第三步,需要在OnDrawFrame()方法中实现对两个三角面的渲染绘制。需要调用glVertextPointer()为绘制流水线指定顶点缓冲。调用glDrawElements()以索引法绘制。

//移入屏幕一段距离

gl.glTranslatef(0.0f,0.0f,-3.0f);

//设置3个方向的旋转gl.glRotatef(xrot,1.0f,0.0f,0.0f);gl.glRotatef(yrot,0.0f,1.0f,0.0f);gl.glRotatef(zrot,0.0f,0.0f,1.0f);//允许设置顶点gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

gl.glVertexPointer(3,GL10.GL_FLOAT,0,this._vertexsBuffer);gl.glDrawElements(GL10.GL_TRIANGLES,6,GL10.GL_UNSIGNED_BYTE,this._indicesBuffer);//取消顶点设置

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//结束绘制

gl.glFinish();更多的绘制模式除了GL_TRAINGLES的方式,还支持以下的绘制方式:GL_POINTS根据顶点缓冲的坐标按顺序绘制顶点。GL_LINES顶点缓冲坐标数据两两成对,每两个顶点胡坐标数据成一组。GL_LINE_STRIF顶点缓冲中的坐标前后成对。GL_LINE_LOOP与GL_LINE_STRIF类似,但把第一个和最后一个相连。GL_TRIANGLES顶点缓冲中的每三个坐标数据为一组,同组的三个顶点将首尾相连成一个封闭的三角。每三个顶点数据独立成组,不用另外的三角共享顶点。GL_TRIANGLE_STRIP三角形带绘制模式。共享顶点。GL_TRIANGLE_FAN三角扇形绘制。以第一个顶点为中心,依次推进形成一个扇形状三角。使用GL_TRIANGLES能够绘制出任何形状,但是用GL_TRIANGLE_STRIP和GL_TIANGLE_FAN有时能减少顶点数量,提高渲染速度。绘制平面平面是许多复杂立体几何体的基本组成,也是许多三维立体对象的承载体。步骤:第一步,需要设定一个原点。第二步,根据长宽确定边界。第三步,根据行列缺定二维网格数据以及细分反案,从而划分出若干个三角面。第四步,将所有三角面的顶点数据依次写入顶点缓冲。第五步,渲染所有三角面。Vertex3f类便于顶点数据的创建RectanglePlane类publicclassVertex3f{publicfloatx=0.0f;publicfloaty=0.0f;publicfloatz=0.0f;publicVertex3f(floatx,floaty,floatz){this.x=x;this.y=y;this.z=z;}}publicclassRectanglePlane{privateint_row=10;//行数privateint_column=10;//列数privatefloat_width=10.0f;//宽度privatefloat_height=10.0f;//高度privateFloatBuffer_planeBuffer;publicRectanglePlane(floatwidth,floatheight,introw,intcolumn){this._width=width;this._height=height;this._row=row;this._column=column;//创建图形数据this.createGraphics();}绘制平面createGraphics()方法用于图形顶点数据的创建,draw()进行绘制在GLRender类中创建一个RectanglePlane类型的矩形平面对象,并传入相关参数。给场景添加光照。privatevoidcreateGraphics(){//设置原点Vertex3fpos=newVertex3f(0.0f,0.0f,0.0f);

//设置网格顶点

Vertex3fvertex[][]=newVertex3f[this._row][this._column];//near

floatsx=pos.x-this._width/2;floatsy=pos.y-this._height/2;

for(inti=0;i<this._row;i++){for(intj=0;j<this._column;j++){//nearfloatnearX=sx+j*(this._width/((float)this._column-1));floatnearY=sy+i*(this._height/((float)this._row-1));floatnearZ=pos.z;

vertex[i][j]=newVertex3f(nearX,nearY,nearZ);}}

//设置三角形顶点

intlen=(this._row-1)*(this._column-1)*2*3;

intindex=0;for(inti=0;i<this._row-1;i++){for(intj=0;j<this._column-1;j++){//planetri[index+0]=vertex[i+1][j+1];tri[index+1]=vertex[i+1][j];tri[index+2]=vertex[i][j];tri[index+3]=vertex[i][j];tri[index+4]=vertex[i][j+1];tri[index+5]=vertex[i+1][j+1];index+=6;}}//设置顶点缓冲

intlen2=len*3;float[]plane=newfloat[len2];intindex2=0;for(inte=0;e<len;e++){plane[index2]=tri[e].x;plane[index2+1]=tri[e].y;plane[index2+2]=tri[e].z;index2+=3;}this._planeBuffer=Util.getFloatBuffer(plane);绘制平面draw()进行绘制在GLRender类中创建一个RectanglePlane类型的矩形平面对象,并传入相关参数。给场景添加光照。publicvoiddraw(GL10gl){//允许设置顶点gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

//绘制平面

gl.glVertexPointer(3,GL10.GL_FLOAT,0,this._planeBuffer);gl.glDrawArrays(GL10.GL_TRIANGLES,0,(this._row-1)*(this._column-1)*2*3);//取消顶点设置

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//绘制结束

gl.glFinish();}privateRectanglePlane_rectanglePlane=newRectanglePlane(10.0f,10.0f,10,10);//定义环境光(r,g,b,a)privateFloatBufferlightAmbient=FloatBuffer.wrap(newfloat[]{0.5f,0.5f,0.5f,1.0f});//定义漫射光privateFloatBufferlightDiffuse=FloatBuffer.wrap(newfloat[]{1.0f,1.0f,1.0f,1.0f});//光源的位置privateFloatBufferlightPosition=FloatBuffer.wrap(newfloat[]{0.0f,0.0f,2.0f,1.0f});//OnSurfaceCreated//设置环境光

gl.glLightfv(GL10.GL_LIGHT1,GL10.GL_AMBIENT,lightAmbient);//设置漫射光

gl.glLightfv(GL10.GL_LIGHT1,GL10.GL_DIFFUSE,lightDiffuse);//设置光源的位置

gl.glLightfv(GL10.GL_LIGHT1,GL10.GL_POSITION,lightPosition);//启用一号光源

gl.glEnable(GL10.GL_LIGHT1);//开启光源gl.glEnable(GL10.GL_LIGHTING);//OnDrawFrame

//移入屏幕一段距离

gl.glTranslatef(0.0f,0.0f,-6.0f);//设置3个方向的旋转gl.glRotatef(xrot,1.0f,0.0f,0.0f);gl.glRotatef(yrot,0.0f,1.0f,0.0f);gl.glRotatef(zrot,0.0f,0.0f,1.0f);//绘制图形this._rectanglePlane.draw(gl);圆形平面圆形平面在需要模拟地平线的时候能派上用场。第一步,设定原点,根据设定的长度半径确定边界。第二步,根据设定的行列数,确定一个二维网格数据,以行为单位,把同行的顶点数据进行旋转变换,从而组成一个闭合的圆形(绕Y轴进行旋转变换),圆形的半径随行数递减直至圆心位置。第三步,根据网格数据将网格细分为若干个三角形。第四步,将所有三角形的顶点依次写入顶点缓冲。第五步,渲染所有三角形面。创建一个CirclePlane类用于圆形平面的绘制。也要创建一个Vertex3f数组。publicclassCirclePlane{privateint_row=10;//行数privateint_column=20;//列数privatefloat_radius=5.0f;//半径privateFloatBuffer_planeBuffer;publicCirclePlane(floatradius,introw,intcolumn){this._radius=radius;this._row=row;this._column=column;//创建图形数据this.createGraphics();}//设置网格顶点

Vertex3fvertex[][]=newVertex3f[this._row][this._column];for(inti=0;i<this._row;i++){floatangle=0.0f;Vertex3ftmpPos=newVertex3f(0.0f,this._radius-i*(this._radius/(this._

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论