移动应用开发课件:2D与3D应用_第1页
移动应用开发课件:2D与3D应用_第2页
移动应用开发课件:2D与3D应用_第3页
移动应用开发课件:2D与3D应用_第4页
移动应用开发课件:2D与3D应用_第5页
已阅读5页,还剩86页未读 继续免费阅读

下载本文档

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

文档简介

#132D与3D应用刘宁Email:liuning2@Android平台提供了两类动画TweenAnimation补间动画,即通过对场景里的对象不断做图像变换(平移、缩放、旋转)产生动画效果

FrameAnimation帧动画,即顺序播放事先做好的图像,跟电影类似。类似GIFAndroid的动画2Tween动画通过对View的内容完成一系列的图形变换(包括平移、缩放、旋转、改变透明度)来实现动画效果。具体来讲,预先定义一组指令,这些指令指定了图形变换的类型、触发时间、持续时间。这些指令可以是以XML文件方式定义,也可以是以源代码方式定义。程序沿着时间线执行这些指令就可以实现动画效果。补间动画简介3动画的进度使用Interpolator控制LinearInterpolator实现了匀速效果Accelerateinterpolator实现了加速效果DecelerateInterpolator实现了减速效果还可以定义自己的Interpolator子类,实现抛物线、自由落体等物理效果。补间动画简介4动画的运行模式有两种:独占模式,即程序主线程进入一个循环,根据动画指令不断刷新屏幕,直到动画结束;中断模式,即有单独一个线程对时间计数,每隔一定的时间向主线程发通知,主线程接到通知后更新屏幕;补间动画简介5图形变换通过仿射矩阵实现。图形变换是线性代数基本知识。简单来说就是,每种变换都是一次矩阵运算。在Android中,Canvas类中包含当前矩阵,当调用Canvas.drawBitmap(bmp,x,y,Paint)绘制时,android会先把bmp做一次矩阵运算,然后将运算的结果显示在Canvas上。这样,编程人员只需不断修改Canvas的矩阵并刷新屏幕,View里的对象就会不停的做图形变换,动画就形成了。补间动画简介6Animation类及其子类是动画的核心模块,它实现了各种动画效果,如平移、缩放、旋转、改变透明度等。Animation类及其子类7Animation类及其子类8Interpolator定义了动画的变化速度,可以实现匀速、正加速、负加速Interpolator类及其子类9对于LinearInterpolator,变化率是个常数,即f(x)=x.Interpolator类及其子类10对于AccelerateInterpolator,开始变化很慢,然后逐渐变快,即f(x)=x*x或者f(x)=pow(x,2*mFactor)Interpolator类及其子类11AccelerateDecelerateInterpolator,变化率开始和结束都很慢,但中间很快,即f(x)=(cos((x+1)*PI)/2.0f)+0.5f.Interpolator类及其子类12Transformation记录了仿射矩阵Matrix,动画每触发一次,会对原来的矩阵做一次运算,View的Bitmap与这个矩阵相乘就可实现相应的操作(旋转、平移、缩放等)。Transformation类封装了矩阵和alpha值,它有两个重要的成员,一是mMatrix,二是mAlpha。Transformation类13view创建动画对象,设置动画属性,调用invalidate刷新屏幕,启动动画;invalidate方法触发了onDraw函数;在onDraw函数中:调用动画的getTransformation方法,得到当前时间点的矩阵将该矩阵设置成Canvas的当前矩阵调用canvas的drawBitmap方法,绘制屏幕。判断getTransformation的返回值,若为真,调用invalidate方法,刷新屏幕进入下一桢;若为假,说明动画完成。View中对Animation的实现1415在xml文件中定义Animation在资源文件夹中创建xml文件/res/anim/anim.xml在代码中通过AnimationUtil.load加载这个xml文件创建Animation对象再通过View.startAnimation开始动画如何使用Animation?16或者通过代码动态创建Animation对象位移,形变等Animation和Interpolator的使用,请自行查阅SDK当有多种Animation同时进行时,会用到AnimationSet如何使用Animation?17Android3D绘图OpenGL(OpenGraphicsLibrary)定义了一个跨编程语言、跨平台的程序接口规格,是一个性能卓越的三维图形标准。为游戏和应用程序提供虚拟的景深,成为当今增强应用程序(尤其是游戏)真实感的重要手段之一。Android的软件开发包提供了对OpenGLES的实现。OpenGL&OpenGLES19我们周围的世界并不是二维的,而是一个带有深度的三维空间。为游戏和应用程序提供虚拟的景深,成为当今增强应用程序(尤其是游戏)真实感的重要手段之一。Android的软件开发包提供了对OpenGLES的实现。OpenGL&OpenGLES20在PC领域,3DAPI主要为OpenGL及DirectX,一般主流的游戏和显卡均支持这两种渲染方式。DirectX在Windows平台上具有较大的优势,但OpenGL却具有更好的跨平台性。OpenGL&OpenGLES21OpenGL(OpenGraphicsLibrary)定义了一个跨编程语言、跨平台的程序接口规格,是一个性能卓越的三维图形标准。是一个专业的图形程序接口,是一个功能强大、调用当便的底层图形库。在专业高端绘图领域,OpenGL比DirectX更有优势。OpenGL&OpenGLES22OpenGLES(OpenGLforEmbeddedSystems)是专为内嵌和移动设备设计的一个2D/3D轻量图形库,它是基于OpenGLAPI设计的,是OpenGL三维图形API的子集。基于OpenGL桌面标准,受到了所有主流移动平台的支持,包括Android、WindowsMobile、Symbian、AppleiPhone等。OpenGL&OpenGLES2324OpenGLES是从OpenGL裁剪定制而来的,去除了四边形(GL_QUADS)、多边形(GL_POLYGONS)等复杂图元等许多非绝对必要的特性。OpenGLES现主要有两种版本:OpenGLES1.x针对固定管线硬件,OpenGLES2.x针对可编程管线硬件。OpenGL&OpenGLES25AndroidSDK2.1及以下版本,都只支持OpenGLES1.1(SDK完整支持OpenGLES1.0,但并不完整支持OpenGLES1.1)Android2.2对OpenGLES2.0进行支持。

OpenGL&OpenGLES26OpenGL是一个跨平台的API,数据类型的大小会随使用的编程语言以及处理器(64位,32位,16位)等的不同而不同,所以OpenGL定义了自己的数据类型。当传递数据到OpenGL时,使用这些OpenGL的数据类型,能保证传递数据的尺寸和精度正确。

数据类型27GLenum:用于GL枚举的无符号整型。通常用于通知OpenGL由指针传递的存储于数组中数据的类型(例如,GL_FLOAT用于指示数组由GLfloat组成)。GLboolean:用于单布尔值。OpenGLES还定义了其自己的“真”和“假”值(GL_TRUE和GL_FALSE)以避免平台和语言的差别。当向OpenGL传递布尔值时,请使用这些值而不是使用YES或NO(尽管由于它们的定义实际没有区别,即使你不小心使用了YES或NO。但是,使用GL-定义值是一个好的习惯。)GLbitfield:用于将多个布尔值(最多32个)打包到单个使用位操作变量的四字节整型。我们将在第一次使用位域变量时详细介绍,请参阅wikipedia

GLbyte:有符号单字节整型,包含数值从-128到127GLshort:有符号双字节整型,包含数值从−32,768到32,767数据类型28GLint:有符号四字节整型,包含数值从−2,147,483,648到2,147,483,647GLsizei:有符号四字节整型,用于代表数据的尺寸(字节),类似于C中的size_t

GLubyte:无符号单字节整型,包含数值从0到255。GLushort:无符号双字节整型,包含数值从0到65,535GLuint:无符号四字节整型,包含数值从0到4,294,967,295GLfloat:四字节精度IEEE754-1985

浮点数GLclampf:这也是四字节精度浮点数,但OpenGL使用GLclampf特别表示数值为0.0到1.0GLvoid:void值用于指示一个函数没有返回值,或没有参数

GLfixed:定点数使用整型数存储实数。由于大部分计算机处理器在处理整型数比处理浮点数快很多,这通常是对3D系统的优化方式。但因为iPhone具有用于浮点运算的矢量处理器,我们将不讨论定点运算或GLfixed数据类型。

GLclampx:另一种定点型,用于使用定点运算来表示0.0到1.0之间的实数。正如GLfixed,我们不会讨论或使用它。数据类型29顶点Vertex3D图像的最小单位称为点(point)或者顶点vertex

。它们代表三维空间中的一个点,并用来建造更复杂的物体。多边形就是由点构成,而物体是由多个多边形组成。尽管通常OpenGL支持多种多边形,但OpenGLES只支持三边形(即三角形)。

在OpenGL中你可以声明少至二维坐标(X,Y),多至四维(X,Y,Z,W)。W轴是可选的,默认的值是1.0。Z轴也是可选的,默认为0。大多数情况下,都将用到3个主要的坐标(X,Y,Z),而W一般都是被用来作为占位符。基本术语30OpenGL坐标系:OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点中心左边的坐标值是负值右边的是正值移向屏幕低端的是负值顶端的是正值移入屏幕深度的是负值移出的是正值基本术语31三角形Triangle三角形需要三个点才能创建。因此在OpenGL中,我们使用3个顶点来创建一个三角形。不像真实世界中的物体,OpenGL中的多边形通常都不会有两面。它们只有一面,被当做frontface(前面),三角形只有其frontface面对观察者时才可见。可以设置OpenGL将多边形作为两面处理,但默认状态下,三角形只有一个可见面。通过知道哪一个面是多边形的前面或可见面,才能使OpenGL只做一半的计算,从而节省计算量。

基本术语32三角形Triangle通常情况下,三角形是一个大物体的一部分,其面对物体内部的一面永远也不可见。不被绘制的一面称为backface(背面),OpenGL是通过观察顶点的绘制次序来确定frontface和backface的。以反时针次序绘制顶点的构成的面是frontface(默认,可以改变)。以顺时针次序绘制顶点的构成的面是backface。基本术语33三角形Triangle下图中,左边青色的三角形是backface,因此将不可见。而右方的三角形是frontface,所以将被绘制。基本术语34多边形Polygon多边形是至少有3个连接着的点组成的一个对象。三角形也是一个多边形。

图元Primitives一个Primitive是一个三维的对象,使用三角形或者多边形创建。基本术语35构造一个自己的Renderer类引入Renderer接口:创建一个GLRender类实现Renderer接口:

构建一个3D开发的基本框架import

android.opengl.GLSurfaceView.Renderer;public

classGLRenderimplementsRenderer{}36在GLRender类中实现以下3个抽象方法:当窗口被创建时需要调用onSurfaceCreat()

当窗口的大小改变时调用onSurfaceChanged()

而所有的绘图操作都在onDrawFrame()方法中进行构建一个3D开发的基本框架public

voidonDrawFrame(GL10gl){}public

voidonSurfaceChanged(GL10gl,intwidth,intheight){}public

voidonSurfaceCreated(GL10gl,EGLConfigconfig){}37当窗口被创建时需要调用onSurfaceCreate,可以在这里对OpenGL做一些初始化工作,例如:

构建一个3D开发的基本框架//启用阴影平滑gl.glShadeModel(GL10.GL_SMOOTH);//黑色背景四个参数分别是(r,g,b,alpha)gl.glClearColor(0,0,0,0);//设置深度缓存gl.glClearDepthf(1.0f);//启用深度测试gl.glEnable(GL10.GL_DEPTH_TEST);//所作深度测试的类型gl.glDepthFunc(GL10.GL_LEQUAL);//告诉系统对透视进行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);38当窗口大小发生改变时系统将调用onSurfaceChange方法,可以在该方法中设置OpenGL场景大小,如:

为屏幕设置透视图,使得越远的物体开起来越小

构建一个3D开发的基本框架//设置OpenGL场景的大小四个参数分别是(x,y,width,height)gl.glViewport(0,0,width,height);//设置投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);//重置投影矩阵gl.glLoadIdentity();//设置视口的大小floatratio=(float)width/height;gl.glFrustumf(-ratio,ratio,-1,1,1,10);//选择模型观察矩阵gl.glMatrixMode(GL10.GL_MODELVIEW);//重置模型观察矩阵gl.glLoadIdentity();39当需要执行绘制图操作的时候调用onDrawFrame。绘图前,需要将屏幕清除成前面所指定的颜色,清除尝试缓存并且重置场景,如:构建一个3D开发的基本框架//清除屏幕和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);//重置当前的模型观察矩阵gl.glLoadIdentity();40最后只要调用GLSurfaceView类的setRenderer方法,将我们自己自己构建的GLRender类设置为默认Renderer,并通过setContentView方法使Activity显示一个GLSurfaceView即可。构建一个3D开发的基本框架Rendererrender=newGLRender();/**Calledwhentheactivityisfirstcreated.*/@Overridepublic

voidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);GLSurfaceViewglView=newGLSurfaceView(this);glView.setRenderer(render);setContentView(glView);}41OpenGL中绘制的任何模型都会被分解为三角形和四边形。有了之前介绍的框架,只需要在GLRender类的onDrawFrame的方法中添加与绘图相关的绘制代码即可。简单绘图42定义三角形顶点数组定义了一个怎样的三角形?简单绘图-三角形int

one=0x10000;

//三角形三个顶点

privateIntBuffertriggerBuffer=IntBuffer.wrap(new

int[]{0,one,0,//上顶点

-one,-one,0,//左下点

one,-one,0,});//右下点;43重置当前模型的观察矩阵清除虚拟世界中的一切旋转,移动或其他变化并将观察者置于原点开启顶点设置功能简单绘图-三角形//重置当前的模型观察矩阵gl.glLoadIdentity();//允许设置顶点gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);44设置顶点数据第二行是通知OpenGL清除以前的一切图形并将其设为clear颜色。glClear()的两个参数是什么意思?简单地说,它们是存储与位域中的常量。OpenGL保存了一系列缓存(buffers),即用于绘图各方面的内存块。将这两个值进行逻辑或是通知OpenGL清除两个不同的缓存–颜色缓存(colorbuffer)和深度缓存(depthbuffer)。颜色缓存保存当前帧各像素的颜色(基本等同于你在屏幕上看到的)。深度缓存保存每个潜在像素离观察者距离的信息。简单绘图-三角形//定义背景颜色为灰色四个参数分别是什么?gl.glClearColor(0.7f,0.7f,0.7f,1f);//清除屏幕和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);45设置顶点数据由于我们使用顶点数组,我们必须通知OpenGL顶点的数组在什么地方。顶点数组是一个C数组,每三个值代表一个顶点。简单绘图-三角形//设置三角形gl.glVertexPointer(3,GL10.GL_FIXED,0,triggerBuffer);//三角形三个顶点

privateIntBuffertriggerBuffer=IntBuffer.wrap(new

int[]{0,one,0,//上顶点

-one,-one,0,//左下点

one,-one,0,});//右下点;之前定义的顶点数组46设置顶点数据publicabstractvoidglVertexPointer(intsize,inttype,intstride,Bufferpointer)Size用于描述顶点的尺寸,由于本例中使用的是XYZ坐标系,所以这里是3Type描述了顶点的类型,由于本例中数据是固定的,所以使用了GL_FIXEDStride描述了步长

Pointer顶点缓存,即之前定义的顶点数组简单绘图-三角形//设置三角形gl.glVertexPointer(3,GL10.GL_FIXED,0,triggerBuffer);47通知OpenGL通过刚才提交的顶点数组来绘制三角形

publicabstractvoidglDrawArrays(intmode,intfirst,intcount)Mode描述了绘制的模式,使用GL_TRIANGLES来绘制三角形。尽管OpenGLES不支持绘制三角形之外的四边形或其他多边形,但它仍然支持一些其他绘图模式,如绘制点,线,线回路,三角形条和三角形扇。

First开始位置Count要绘制的顶点数简单绘图-三角形//绘制三角形gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);48禁止先前启动了的特性以保证不会被其他地方的代码弄混运行结果简单绘图-三角形//取消顶点设置gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);49OpenGLES并不支持四边形。那如果你想画菱形怎么办?只能通过三角形来定义菱形——一个菱形可以通过两个三角形构成。如何实现?创建两个三角形顶点数组?简单绘图-四边形//三角形三个顶点

private

IntBuffer

triggerBuffer=IntBuffer.wrap(new

int[]{0,one,0,//第一个三角形上顶点

-one,-one,0,//左下点

one,-one,0,//右下点;0,-3*one,0,//第二个三角形下顶点

-one,-one,0,//左上点

one,-one,0,});//右上点;50虽然以上方法确实可行,但是却并不是最优的方案,并且还会重复保存顶点(以上方法共需要保存6个顶点,其中第一个三角形的左下、右下点与第二个三角形的左上、右上点重叠)。实际上我们可以使用trianglestrips(GL_TRIANGLE_STRIP)方法通过四个顶点来绘制正方形。简单绘图-四边形51三角形条的基本概念:第一个三角形条是由前三个顶点构成(索引0,1,2)。第二个三角形条是由前一个三角形的两个顶点加上数组中的下一个顶点构成,继续直到整个数组结束。看下图更清楚–第一个三角形由顶点1,2,3构成,下一个三角形由顶点2,3,4构成,等等:简单绘图-四边形52所以,四边形是这样构成的:通过提交的顶点数组来绘制四边形

简单绘图-四边形//正方形的4个顶点

privateIntBufferquaterBuffer=IntBuffer.wrap(new

int[]{

one,one,0,

-one,one,0,

one,-one,0,

-one,-one,0});gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);53着色有平滑着色、单调着色简单绘图-彩色渲染平滑着色单调着色54单调着色设置当前所使用的颜色设置了当前颜色之后的所绘制的所有颜色都使用当前颜色。简单绘图-彩色渲染//设置当前色为红色

gl.glColor4f(1.0f,0.0f,0.0f,1.0f);55平滑着色OpenGLES允许将每个顶点使用的颜色置于一个颜色数组(colorarray)中。如果选择使用颜色数组,那么需要为每个顶点设置颜色。

三个顶点,每个顶点四个值简单绘图-彩色渲染//三角形的顶点颜色值(r,g,b,a)

privateIntBuffercolorBuffer=IntBuffer.wrap(new

int[]{

one,0,0,one,0,one,0,one,0,0,one,one,});56平滑着色开启颜色渲染功能为三角形设置定义好的颜色关闭颜色渲染功能简单绘图-彩色渲染//设置颜色数组gl.glEnableClientState(GL10.GL_COLOR_ARRAY);gl.glColorPointer(4,GL10.GL_FIXED,0,colorBuffer);gl.glDisableClientState(GL10.GL_COLOR_ARRAY);57绕某轴旋转定义旋转角度变量在onDrawFrame里设置旋转publicabstractvoidglRotatef(floatangle,floatx,floaty,floatz)Angle定义了旋转的角度

x,y,z共同决定了旋转轴的方向改变旋转角度简单绘图-旋转float

rotate;gl.glRotatef(rotate,0.0f,1.0f,0.0f);

//绕y轴rotate

-=0.5f;58例:绘制一个四棱锥与绘制三角形相似,重点都在于构建顶点坐标构建顶点坐标时,需要按照逆时针的方向来绘制(WHY?按照顺时针绘制会怎么样?)简单绘图-3D空间59四棱锥由四个三角形组成简单绘图-3D空间

private

IntBuffer

triggerBuffer=IntBuffer.wrap(new

int[]{0,one,0,-one,-one,0,one,-one,one,0,one,0,one,-one,one,one,-one,-one,0,one,0,one,-one,-one,-one,-one,-one,0,one,0,-one,-one,-one,-one,-one,one});60使用循环把四个面都绘制出来简单绘图-3D空间//绘制四棱锥

for(inti=0;i<4;i++){gl.glDrawArrays(GL10.GL_TRIANGLE,i*3,3);}61OpenGLES中具有的两种不同的视口类型。正交(orthogonal)透视(perspective)OpenGL---透视62正交视线永远不会交汇而且物体不会改变其大小。没有透视效果。

OpenGL---透视63透视

物体会随着移远而越来越小,视线会在物体移离观察者时最终交汇。这是对真实视觉的模拟,人们就是以这种方式观察世界的。OpenGL---透视64rightneartopOpenGL---透视65设置正交视口通过glOrthof()通知OpenGLES你希望使用正交视口OpenGL---透视

floatratio=_width/_height;//屏幕宽长比//orthographic:gl.glOrthof(-1,//left1,//right-1/ratio,//bottom1/ratio,//top0.01f,//near100.0f);//far设定视口空间的宽度为两个单位,沿x轴从-1.0到+1.0。

定义空间的X和Y坐标的宽高比与视窗的宽高比(也就是全屏时的宽高比)一样,确保视口的X和Y坐标遵循一样的比例。

66near

参数:说明了视口开始的位置。如果我们站在原点处,视口就位于我们的面前,习惯上使用.01

或.001

作为正交视口的起点。使得视口处于原点“前方”一点点。

far描述观察的深度,根据你程序的需要来设定。设置正交视口定义了near(远)和far(近)范围来描述观察的深度。OpenGL---透视floatratio=_width/_height;//屏幕长宽比//orthographic:gl.glOrthof(-1,//left1,//right-1/ratio,//bottom1/ratio,//top0.01f,//near100.0f);//far67调用glOrthof()之后,我们使用视窗矩形来调用glViewport()。

切换了MatrixMode到GL10.GL_MODELVIEW,设置OpenGL接受关于改变model绘制方式的调用。

OpenGL---透视

gl.glViewport(0,0,(int)_width,(int)_height);68调用了glEnable()并使用参数GL10.GL_DEPTH_TEST。使OpenGLES检查对象的z方向的顺序。如果我们没有enable它,我们将看到最后被绘制的对象一直显示在最前面。这意味着,即使这个物体本来应该被更近更大的物体遮盖,我们依然可以看到它。

OpenGL---透视

gl.glMatrixMode(GL10.GL_MODELVIEW);

gl.glEnable(GL10.GL_DEPTH_TEST);69设置透视视口随着视线越来越远,可以看到更广阔的世界物体随着远离观察者而变小使用透视时可见空间的形状称为锥台(frustum)OpenGL---透视70视野(fieldofvision)

由两个角度定义的:伸出双臂手掌合拢伸向前方。你的手臂现在指向你自己锥台的z轴。现在慢慢分开你的双臂,定义了一个逐渐增大的角度。这就是用于定义观察锥台的两个角度之一,它定义了视野的宽度。OpenGL---透视71视野(fieldofvision)

上下展开你的双臂,定义了另一个角度。如果你的双手间距只有三厘米,那么角度将非常小。这称为窄视野。如果你双手分开两米,视野的宽度变得很大。这就是所谓宽视角(广角)。OpenGL---透视72设置透视视口我们选择一个中间值,45°。使用这个值,我们怎样计算我们的观察锥台?想象一下,从顶部看锥台是什么样子。OpenGL---透视45°

下面是示意图:

73设置透视视口正切函数定义为直角对边与相邻边的比率。

锥台远端宽度的一半就是视野角度正切的一半。将此值乘以near值,就可以得到right值。

right值取反就是left。OpenGL---透视nearright(45/2)°right=near*tan(45/2)74设置透视视口通过glFrustumf()通知OpenGLES你希望使用正交视口OpenGL---透视

floatsize=0.01f*(float)Math.tan(Math.toRadians(45.0)/2);

floatratio=_width/_height;//屏幕长宽比//perspective:gl.glFrustumf(-size,//leftsize,//right

-size/ratio,//bottomsize/ratio,//top0.01f,//near100.0f);//farsize=near*tan(45/2),为左右视野的宽度定义空间的X和Y坐标的宽高比与视窗的宽高比(也就是全屏时的宽高比)一样,确保视口的X和Y坐标遵循一样的比例。

rightneartop75OpenGL---透视透视效果随着几何体远离你,它们会变得越来越小,正像火车铁轨一样。正交效果第一个四棱锥后面的四棱锥完全被第一个挡住了。因为没有透视,后面的各几何体的形状完全取决于其前方的物体。

76OpenGL在没有设置光效的情况下仍然可以看见东西。它只是提供一种十分单调的整体光让我们看到物体。但是如果不定义光效,物体看上去都很单调。OpenGL---光效77OpenGLES实际上定义了两种shademodel,GL_FLAT

和GL_SMOOTH。

GL_FLAT将指定三角形上的每个像素都同等对待。多边形上的每个像素都具有相同的颜色,阴影等。它的计算比每个像素按不同方法计算更为廉价,但是在这种方式下,物体看上去极为不真实。

OpenGL---光效78要使3D物体尽量真实,应该使用GL_SMOOTH

绘图模式,它使用了一种平滑但较快速的阴影算法,称为Gouraud算法。GL_SMOOTH是默认值。

OpenGL---光效79首先启动光效。默认情况下,手工指定光效是被禁止的。通常情况下,光效只需在设定时启动一次。不需要在绘图开始前后打开和关闭。启动光效后的效果:

OpenGL---光效//如果不启用GL_LIGHTING光就什么都看不见gl.glEnable(GL10.GL_LIGHTING);80启动了光效,但是没有创建任何光源。除清除缓存用的灰色外,任何绘制的物体都被渲染成绝对的黑色。如果只对光源进行设置、定位甚至启用,光源不会工作,除非启用GL_LIGHTING。OpenGLES允许你创建8个光源。有一个常量对应于这些光源中的一个,常量为GL_LIGHT0

到GL_LIGHT7。可以任意组合这些光源中的五个。下面是“打开”第一个光源GL_LIGHT1的方法:OpenGL---光效gl.glEnable(GL10.GL_LIGHT1);//启用一号光源81一旦启动了光源,则必须设置光源的一些属性。一般情况下,有三个不同的要素用来定义光源。光效三要素在OpenGLES中,光由三个元素组成:

环境元素(ambientcomponent)散射元素(diffusecomponent)高光元素(specularcomponent)OpenGL---光效82高光元素(specularcomponent)定义了光线直接照射并反射到观察者从而形成了物体上的“热点”或光泽。光点的大小取决于一些因素,但是如果你看到如上图黄球所示一个区域明显的光斑,那通常就是来自于一个或多个光源的高光部分。散射元素(diffusecomponent)定义了比较平均的定向光源,在物体面向光线的一面具有光泽。

环境光(ambientcomponent)没有明显的光源。其光线折射与许多物体,因此无法确定其来源。环境元素平均作用于场景中的所有物体的所有面。OpenGL---光效83环境光(ambient)光效中有越多的环境元素,就越不会产生引入注目的效果。场景中的总环境光效是由所有启动光源的环境光组合在一起所决定的。如果你使用了

温馨提示

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

评论

0/150

提交评论