版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
#132D與3D應(yīng)用劉寧Email:liuning2@Android平臺(tái)提供了兩類(lèi)動(dòng)畫(huà)TweenAnimation補(bǔ)間動(dòng)畫(huà),即通過(guò)對(duì)場(chǎng)景里的對(duì)象不斷做圖像變換(平移、縮放、旋轉(zhuǎn))產(chǎn)生動(dòng)畫(huà)效果
FrameAnimation幀動(dòng)畫(huà),即順序播放事先做好的圖像,跟電影類(lèi)似。類(lèi)似GIFAndroid的動(dòng)畫(huà)2Tween動(dòng)畫(huà)通過(guò)對(duì)View的內(nèi)容完成一系列的圖形變換(包括平移、縮放、旋轉(zhuǎn)、改變透明度)來(lái)實(shí)現(xiàn)動(dòng)畫(huà)效果。具體來(lái)講,預(yù)先定義一組指令,這些指令指定了圖形變換的類(lèi)型、觸發(fā)時(shí)間、持續(xù)時(shí)間。這些指令可以是以XML文件方式定義,也可以是以源代碼方式定義。程序沿著時(shí)間線(xiàn)執(zhí)行這些指令就可以實(shí)現(xiàn)動(dòng)畫(huà)效果。補(bǔ)間動(dòng)畫(huà)簡(jiǎn)介3動(dòng)畫(huà)的進(jìn)度使用Interpolator控制LinearInterpolator實(shí)現(xiàn)了勻速效果Accelerateinterpolator實(shí)現(xiàn)了加速效果DecelerateInterpolator實(shí)現(xiàn)了減速效果還可以定義自己的Interpolator子類(lèi),實(shí)現(xiàn)拋物線(xiàn)、自由落體等物理效果。補(bǔ)間動(dòng)畫(huà)簡(jiǎn)介4動(dòng)畫(huà)的運(yùn)行模式有兩種:獨(dú)占模式,即程序主線(xiàn)程進(jìn)入一個(gè)循環(huán),根據(jù)動(dòng)畫(huà)指令不斷刷新屏幕,直到動(dòng)畫(huà)結(jié)束;中斷模式,即有單獨(dú)一個(gè)線(xiàn)程對(duì)時(shí)間計(jì)數(shù),每隔一定的時(shí)間向主線(xiàn)程發(fā)通知,主線(xiàn)程接到通知后更新屏幕;補(bǔ)間動(dòng)畫(huà)簡(jiǎn)介5圖形變換通過(guò)仿射矩陣實(shí)現(xiàn)。圖形變換是線(xiàn)性代數(shù)基本知識(shí)。簡(jiǎn)單來(lái)說(shuō)就是,每種變換都是一次矩陣運(yùn)算。在Android中,Canvas類(lèi)中包含當(dāng)前矩陣,當(dāng)調(diào)用Canvas.drawBitmap(bmp,x,y,Paint)繪制時(shí),android會(huì)先把bmp做一次矩陣運(yùn)算,然后將運(yùn)算的結(jié)果顯示在Canvas上。這樣,編程人員只需不斷修改Canvas的矩陣并刷新屏幕,View里的對(duì)象就會(huì)不停的做圖形變換,動(dòng)畫(huà)就形成了。補(bǔ)間動(dòng)畫(huà)簡(jiǎn)介6Animation類(lèi)及其子類(lèi)是動(dòng)畫(huà)的核心模塊,它實(shí)現(xiàn)了各種動(dòng)畫(huà)效果,如平移、縮放、旋轉(zhuǎn)、改變透明度等。Animation類(lèi)及其子類(lèi)7Animation類(lèi)及其子類(lèi)8Interpolator定義了動(dòng)畫(huà)的變化速度,可以實(shí)現(xiàn)勻速、正加速、負(fù)加速I(mǎi)nterpolator類(lèi)及其子類(lèi)9對(duì)于LinearInterpolator,變化率是個(gè)常數(shù),即f(x)=x.Interpolator類(lèi)及其子類(lèi)10對(duì)于AccelerateInterpolator,開(kāi)始變化很慢,然后逐漸變快,即f(x)=x*x或者f(x)=pow(x,2*mFactor)Interpolator類(lèi)及其子類(lèi)11AccelerateDecelerateInterpolator,變化率開(kāi)始和結(jié)束都很慢,但中間很快,即f(x)=(cos((x+1)*PI)/2.0f)+0.5f.Interpolator類(lèi)及其子類(lèi)12Transformation記錄了仿射矩陣Matrix,動(dòng)畫(huà)每觸發(fā)一次,會(huì)對(duì)原來(lái)的矩陣做一次運(yùn)算,View的Bitmap與這個(gè)矩陣相乘就可實(shí)現(xiàn)相應(yīng)的操作(旋轉(zhuǎn)、平移、縮放等)。Transformation類(lèi)封裝了矩陣和alpha值,它有兩個(gè)重要的成員,一是mMatrix,二是mAlpha。Transformation類(lèi)13view創(chuàng)建動(dòng)畫(huà)對(duì)象,設(shè)置動(dòng)畫(huà)屬性,調(diào)用invalidate刷新屏幕,啟動(dòng)動(dòng)畫(huà);invalidate方法觸發(fā)了onDraw函數(shù);在onDraw函數(shù)中:調(diào)用動(dòng)畫(huà)的getTransformation方法,得到當(dāng)前時(shí)間點(diǎn)的矩陣將該矩陣設(shè)置成Canvas的當(dāng)前矩陣調(diào)用canvas的drawBitmap方法,繪制屏幕。判斷getTransformation的返回值,若為真,調(diào)用invalidate方法,刷新屏幕進(jìn)入下一楨;若為假,說(shuō)明動(dòng)畫(huà)完成。View中對(duì)Animation的實(shí)現(xiàn)1415在xml文件中定義Animation在資源文件夾中創(chuàng)建xml文件/res/anim/anim.xml在代碼中通過(guò)AnimationUtil.load加載這個(gè)xml文件創(chuàng)建Animation對(duì)象再通過(guò)View.startAnimation開(kāi)始動(dòng)畫(huà)如何使用Animation?16或者通過(guò)代碼動(dòng)態(tài)創(chuàng)建Animation對(duì)象位移,形變等Animation和Interpolator的使用,請(qǐng)自行查閱SDK當(dāng)有多種Animation同時(shí)進(jìn)行時(shí),會(huì)用到AnimationSet如何使用Animation?17Android3D繪圖OpenGL(OpenGraphicsLibrary)定義了一個(gè)跨編程語(yǔ)言、跨平臺(tái)的程序接口規(guī)格,是一個(gè)性能卓越的三維圖形標(biāo)準(zhǔn)。為游戲和應(yīng)用程序提供虛擬的景深,成為當(dāng)今增強(qiáng)應(yīng)用程序(尤其是游戲)真實(shí)感的重要手段之一。Android的軟件開(kāi)發(fā)包提供了對(duì)OpenGLES的實(shí)現(xiàn)。OpenGL&OpenGLES19我們周?chē)氖澜绮⒉皇嵌S的,而是一個(gè)帶有深度的三維空間。為游戲和應(yīng)用程序提供虛擬的景深,成為當(dāng)今增強(qiáng)應(yīng)用程序(尤其是游戲)真實(shí)感的重要手段之一。Android的軟件開(kāi)發(fā)包提供了對(duì)OpenGLES的實(shí)現(xiàn)。OpenGL&OpenGLES20在PC領(lǐng)域,3DAPI主要為OpenGL及DirectX,一般主流的游戲和顯卡均支持這兩種渲染方式。DirectX在Windows平臺(tái)上具有較大的優(yōu)勢(shì),但OpenGL卻具有更好的跨平臺(tái)性。OpenGL&OpenGLES21OpenGL(OpenGraphicsLibrary)定義了一個(gè)跨編程語(yǔ)言、跨平臺(tái)的程序接口規(guī)格,是一個(gè)性能卓越的三維圖形標(biāo)準(zhǔn)。是一個(gè)專(zhuān)業(yè)的圖形程序接口,是一個(gè)功能強(qiáng)大、調(diào)用當(dāng)便的底層圖形庫(kù)。在專(zhuān)業(yè)高端繪圖領(lǐng)域,OpenGL比DirectX更有優(yōu)勢(shì)。OpenGL&OpenGLES22OpenGLES(OpenGLforEmbeddedSystems)是專(zhuān)為內(nèi)嵌和移動(dòng)設(shè)備設(shè)計(jì)的一個(gè)2D/3D輕量圖形庫(kù),它是基于OpenGLAPI設(shè)計(jì)的,是OpenGL三維圖形API的子集。基于OpenGL桌面標(biāo)準(zhǔn),受到了所有主流移動(dòng)平臺(tái)的支持,包括Android、WindowsMobile、Symbian、AppleiPhone等。OpenGL&OpenGLES2324OpenGLES是從OpenGL裁剪定制而來(lái)的,去除了四邊形(GL_QUADS)、多邊形(GL_POLYGONS)等復(fù)雜圖元等許多非絕對(duì)必要的特性。OpenGLES現(xiàn)主要有兩種版本:OpenGLES1.x針對(duì)固定管線(xiàn)硬件,OpenGLES2.x針對(duì)可編程管線(xiàn)硬件。OpenGL&OpenGLES25AndroidSDK2.1及以下版本,都只支持OpenGLES1.1(SDK完整支持OpenGLES1.0,但并不完整支持OpenGLES1.1)Android2.2對(duì)OpenGLES2.0進(jìn)行支持。
OpenGL&OpenGLES26OpenGL是一個(gè)跨平臺(tái)的API,數(shù)據(jù)類(lèi)型的大小會(huì)隨使用的編程語(yǔ)言以及處理器(64位,32位,16位)等的不同而不同,所以O(shè)penGL定義了自己的數(shù)據(jù)類(lèi)型。當(dāng)傳遞數(shù)據(jù)到OpenGL時(shí),使用這些OpenGL的數(shù)據(jù)類(lèi)型,能保證傳遞數(shù)據(jù)的尺寸和精度正確。
數(shù)據(jù)類(lèi)型27GLenum:用于GL枚舉的無(wú)符號(hào)整型。通常用于通知OpenGL由指針傳遞的存儲(chǔ)于數(shù)組中數(shù)據(jù)的類(lèi)型(例如,GL_FLOAT用于指示數(shù)組由GLfloat組成)。GLboolean:用于單布爾值。OpenGLES還定義了其自己的“真”和“假”值(GL_TRUE和GL_FALSE)以避免平臺(tái)和語(yǔ)言的差別。當(dāng)向OpenGL傳遞布爾值時(shí),請(qǐng)使用這些值而不是使用YES或NO(盡管由于它們的定義實(shí)際沒(méi)有區(qū)別,即使你不小心使用了YES或NO。但是,使用GL-定義值是一個(gè)好的習(xí)慣。)GLbitfield:用于將多個(gè)布爾值(最多32個(gè))打包到單個(gè)使用位操作變量的四字節(jié)整型。我們將在第一次使用位域變量時(shí)詳細(xì)介紹,請(qǐng)參閱wikipedia
GLbyte:有符號(hào)單字節(jié)整型,包含數(shù)值從-128到127GLshort:有符號(hào)雙字節(jié)整型,包含數(shù)值從?32,768到32,767數(shù)據(jù)類(lèi)型28GLint:有符號(hào)四字節(jié)整型,包含數(shù)值從?2,147,483,648到2,147,483,647GLsizei:有符號(hào)四字節(jié)整型,用于代表數(shù)據(jù)的尺寸(字節(jié)),類(lèi)似于C中的size_t
GLubyte:無(wú)符號(hào)單字節(jié)整型,包含數(shù)值從0到255。GLushort:無(wú)符號(hào)雙字節(jié)整型,包含數(shù)值從0到65,535GLuint:無(wú)符號(hào)四字節(jié)整型,包含數(shù)值從0到4,294,967,295GLfloat:四字節(jié)精度IEEE754-1985
浮點(diǎn)數(shù)GLclampf:這也是四字節(jié)精度浮點(diǎn)數(shù),但OpenGL使用GLclampf特別表示數(shù)值為0.0到1.0GLvoid:void值用于指示一個(gè)函數(shù)沒(méi)有返回值,或沒(méi)有參數(shù)
GLfixed:定點(diǎn)數(shù)使用整型數(shù)存儲(chǔ)實(shí)數(shù)。由于大部分計(jì)算機(jī)處理器在處理整型數(shù)比處理浮點(diǎn)數(shù)快很多,這通常是對(duì)3D系統(tǒng)的優(yōu)化方式。但因?yàn)閕Phone具有用于浮點(diǎn)運(yùn)算的矢量處理器,我們將不討論定點(diǎn)運(yùn)算或GLfixed數(shù)據(jù)類(lèi)型。
GLclampx:另一種定點(diǎn)型,用于使用定點(diǎn)運(yùn)算來(lái)表示0.0到1.0之間的實(shí)數(shù)。正如GLfixed,我們不會(huì)討論或使用它。數(shù)據(jù)類(lèi)型29頂點(diǎn)Vertex3D圖像的最小單位稱(chēng)為點(diǎn)(point)或者頂點(diǎn)vertex
。它們代表三維空間中的一個(gè)點(diǎn),并用來(lái)建造更復(fù)雜的物體。多邊形就是由點(diǎn)構(gòu)成,而物體是由多個(gè)多邊形組成。盡管通常OpenGL支持多種多邊形,但OpenGLES只支持三邊形(即三角形)。
在OpenGL中你可以聲明少至二維坐標(biāo)(X,Y),多至四維(X,Y,Z,W)。W軸是可選的,默認(rèn)的值是1.0。Z軸也是可選的,默認(rèn)為0。大多數(shù)情況下,都將用到3個(gè)主要的坐標(biāo)(X,Y,Z),而W一般都是被用來(lái)作為占位符?;拘g(shù)語(yǔ)30OpenGL坐標(biāo)系:OpenGL屏幕中心的坐標(biāo)值是X和Y軸上的0.0f點(diǎn)中心左邊的坐標(biāo)值是負(fù)值右邊的是正值移向屏幕低端的是負(fù)值頂端的是正值移入屏幕深度的是負(fù)值移出的是正值基本術(shù)語(yǔ)31三角形Triangle三角形需要三個(gè)點(diǎn)才能創(chuàng)建。因此在OpenGL中,我們使用3個(gè)頂點(diǎn)來(lái)創(chuàng)建一個(gè)三角形。不像真實(shí)世界中的物體,OpenGL中的多邊形通常都不會(huì)有兩面。它們只有一面,被當(dāng)做frontface(前面),三角形只有其frontface面對(duì)觀(guān)察者時(shí)才可見(jiàn)。可以設(shè)置OpenGL將多邊形作為兩面處理,但默認(rèn)狀態(tài)下,三角形只有一個(gè)可見(jiàn)面。通過(guò)知道哪一個(gè)面是多邊形的前面或可見(jiàn)面,才能使OpenGL只做一半的計(jì)算,從而節(jié)省計(jì)算量。
基本術(shù)語(yǔ)32三角形Triangle通常情況下,三角形是一個(gè)大物體的一部分,其面對(duì)物體內(nèi)部的一面永遠(yuǎn)也不可見(jiàn)。不被繪制的一面稱(chēng)為backface(背面),OpenGL是通過(guò)觀(guān)察頂點(diǎn)的繪制次序來(lái)確定frontface和backface的。以反時(shí)針次序繪制頂點(diǎn)的構(gòu)成的面是frontface(默認(rèn),可以改變)。以順時(shí)針次序繪制頂點(diǎn)的構(gòu)成的面是backface。基本術(shù)語(yǔ)33三角形Triangle下圖中,左邊青色的三角形是backface,因此將不可見(jiàn)。而右方的三角形是frontface,所以將被繪制?;拘g(shù)語(yǔ)34多邊形Polygon多邊形是至少有3個(gè)連接著的點(diǎn)組成的一個(gè)對(duì)象。三角形也是一個(gè)多邊形。
圖元Primitives一個(gè)Primitive是一個(gè)三維的對(duì)象,使用三角形或者多邊形創(chuàng)建?;拘g(shù)語(yǔ)35構(gòu)造一個(gè)自己的Renderer類(lèi)引入Renderer接口:創(chuàng)建一個(gè)GLRender類(lèi)實(shí)現(xiàn)Renderer接口:
構(gòu)建一個(gè)3D開(kāi)發(fā)的基本框架import
android.opengl.GLSurfaceView.Renderer;public
classGLRenderimplementsRenderer{}36在GLRender類(lèi)中實(shí)現(xiàn)以下3個(gè)抽象方法:當(dāng)窗口被創(chuàng)建時(shí)需要調(diào)用onSurfaceCreat()
當(dāng)窗口的大小改變時(shí)調(diào)用onSurfaceChanged()
而所有的繪圖操作都在onDrawFrame()方法中進(jìn)行構(gòu)建一個(gè)3D開(kāi)發(fā)的基本框架public
voidonDrawFrame(GL10gl){}public
voidonSurfaceChanged(GL10gl,intwidth,intheight){}public
voidonSurfaceCreated(GL10gl,EGLConfigconfig){}37當(dāng)窗口被創(chuàng)建時(shí)需要調(diào)用onSurfaceCreate,可以在這里對(duì)OpenGL做一些初始化工作,例如:
構(gòu)建一個(gè)3D開(kāi)發(fā)的基本框架//啟用陰影平滑gl.glShadeModel(GL10.GL_SMOOTH);//黑色背景四個(gè)參數(shù)分別是(r,g,b,alpha)gl.glClearColor(0,0,0,0);//設(shè)置深度緩存gl.glClearDepthf(1.0f);//啟用深度測(cè)試gl.glEnable(GL10.GL_DEPTH_TEST);//所作深度測(cè)試的類(lèi)型gl.glDepthFunc(GL10.GL_LEQUAL);//告訴系統(tǒng)對(duì)透視進(jìn)行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);38當(dāng)窗口大小發(fā)生改變時(shí)系統(tǒng)將調(diào)用onSurfaceChange方法,可以在該方法中設(shè)置OpenGL場(chǎng)景大小,如:
為屏幕設(shè)置透視圖,使得越遠(yuǎn)的物體開(kāi)起來(lái)越小
構(gòu)建一個(gè)3D開(kāi)發(fā)的基本框架//設(shè)置OpenGL場(chǎng)景的大小四個(gè)參數(shù)分別是(x,y,width,height)gl.glViewport(0,0,width,height);//設(shè)置投影矩陣gl.glMatrixMode(GL10.GL_PROJECTION);//重置投影矩陣gl.glLoadIdentity();//設(shè)置視口的大小floatratio=(float)width/height;gl.glFrustumf(-ratio,ratio,-1,1,1,10);//選擇模型觀(guān)察矩陣gl.glMatrixMode(GL10.GL_MODELVIEW);//重置模型觀(guān)察矩陣gl.glLoadIdentity();39當(dāng)需要執(zhí)行繪制圖操作的時(shí)候調(diào)用onDrawFrame。繪圖前,需要將屏幕清除成前面所指定的顏色,清除嘗試緩存并且重置場(chǎng)景,如:構(gòu)建一個(gè)3D開(kāi)發(fā)的基本框架//清除屏幕和深度緩存gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);//重置當(dāng)前的模型觀(guān)察矩陣gl.glLoadIdentity();40最后只要調(diào)用GLSurfaceView類(lèi)的setRenderer方法,將我們自己自己構(gòu)建的GLRender類(lèi)設(shè)置為默認(rèn)Renderer,并通過(guò)setContentView方法使Activity顯示一個(gè)GLSurfaceView即可。構(gòu)建一個(gè)3D開(kāi)發(fā)的基本框架Rendererrender=newGLRender();/**Calledwhentheactivityisfirstcreated.*/@Overridepublic
voidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);GLSurfaceViewglView=newGLSurfaceView(this);glView.setRenderer(render);setContentView(glView);}41OpenGL中繪制的任何模型都會(huì)被分解為三角形和四邊形。有了之前介紹的框架,只需要在GLRender類(lèi)的onDrawFrame的方法中添加與繪圖相關(guān)的繪制代碼即可。簡(jiǎn)單繪圖42定義三角形頂點(diǎn)數(shù)組定義了一個(gè)怎樣的三角形?簡(jiǎn)單繪圖-三角形int
one=0x10000;
//三角形三個(gè)頂點(diǎn)
privateIntBuffertriggerBuffer=IntBuffer.wrap(new
int[]{0,one,0,//上頂點(diǎn)
-one,-one,0,//左下點(diǎn)
one,-one,0,});//右下點(diǎn);43重置當(dāng)前模型的觀(guān)察矩陣清除虛擬世界中的一切旋轉(zhuǎn),移動(dòng)或其他變化并將觀(guān)察者置于原點(diǎn)開(kāi)啟頂點(diǎn)設(shè)置功能簡(jiǎn)單繪圖-三角形//重置當(dāng)前的模型觀(guān)察矩陣gl.glLoadIdentity();//允許設(shè)置頂點(diǎn)gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);44設(shè)置頂點(diǎn)數(shù)據(jù)第二行是通知OpenGL清除以前的一切圖形并將其設(shè)為clear顏色。glClear()的兩個(gè)參數(shù)是什么意思?簡(jiǎn)單地說(shuō),它們是存儲(chǔ)與位域中的常量。OpenGL保存了一系列緩存(buffers),即用于繪圖各方面的內(nèi)存塊。將這兩個(gè)值進(jìn)行邏輯或是通知OpenGL清除兩個(gè)不同的緩存–顏色緩存(colorbuffer)和深度緩存(depthbuffer)。顏色緩存保存當(dāng)前幀各像素的顏色(基本等同于你在屏幕上看到的)。深度緩存保存每個(gè)潛在像素離觀(guān)察者距離的信息。簡(jiǎn)單繪圖-三角形//定義背景顏色為灰色四個(gè)參數(shù)分別是什么?gl.glClearColor(0.7f,0.7f,0.7f,1f);//清除屏幕和深度緩存gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);45設(shè)置頂點(diǎn)數(shù)據(jù)由于我們使用頂點(diǎn)數(shù)組,我們必須通知OpenGL頂點(diǎn)的數(shù)組在什么地方。頂點(diǎn)數(shù)組是一個(gè)C數(shù)組,每三個(gè)值代表一個(gè)頂點(diǎn)。簡(jiǎn)單繪圖-三角形//設(shè)置三角形gl.glVertexPointer(3,GL10.GL_FIXED,0,triggerBuffer);//三角形三個(gè)頂點(diǎn)
privateIntBuffertriggerBuffer=IntBuffer.wrap(new
int[]{0,one,0,//上頂點(diǎn)
-one,-one,0,//左下點(diǎn)
one,-one,0,});//右下點(diǎn);之前定義的頂點(diǎn)數(shù)組46設(shè)置頂點(diǎn)數(shù)據(jù)publicabstractvoidglVertexPointer(intsize,inttype,intstride,Bufferpointer)Size用于描述頂點(diǎn)的尺寸,由于本例中使用的是XYZ坐標(biāo)系,所以這里是3Type描述了頂點(diǎn)的類(lèi)型,由于本例中數(shù)據(jù)是固定的,所以使用了GL_FIXEDStride描述了步長(zhǎng)
Pointer頂點(diǎn)緩存,即之前定義的頂點(diǎn)數(shù)組簡(jiǎn)單繪圖-三角形//設(shè)置三角形gl.glVertexPointer(3,GL10.GL_FIXED,0,triggerBuffer);47通知OpenGL通過(guò)剛才提交的頂點(diǎn)數(shù)組來(lái)繪制三角形
publicabstractvoidglDrawArrays(intmode,intfirst,intcount)Mode描述了繪制的模式,使用GL_TRIANGLES來(lái)繪制三角形。盡管OpenGLES不支持繪制三角形之外的四邊形或其他多邊形,但它仍然支持一些其他繪圖模式,如繪制點(diǎn),線(xiàn),線(xiàn)回路,三角形條和三角形扇。
First開(kāi)始位置Count要繪制的頂點(diǎn)數(shù)簡(jiǎn)單繪圖-三角形//繪制三角形gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);48禁止先前啟動(dòng)了的特性以保證不會(huì)被其他地方的代碼弄混運(yùn)行結(jié)果簡(jiǎn)單繪圖-三角形//取消頂點(diǎn)設(shè)置gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);49OpenGLES并不支持四邊形。那如果你想畫(huà)菱形怎么辦?只能通過(guò)三角形來(lái)定義菱形——一個(gè)菱形可以通過(guò)兩個(gè)三角形構(gòu)成。如何實(shí)現(xiàn)?創(chuàng)建兩個(gè)三角形頂點(diǎn)數(shù)組?簡(jiǎn)單繪圖-四邊形//三角形三個(gè)頂點(diǎn)
private
IntBuffer
triggerBuffer=IntBuffer.wrap(new
int[]{0,one,0,//第一個(gè)三角形上頂點(diǎn)
-one,-one,0,//左下點(diǎn)
one,-one,0,//右下點(diǎn);0,-3*one,0,//第二個(gè)三角形下頂點(diǎn)
-one,-one,0,//左上點(diǎn)
one,-one,0,});//右上點(diǎn);50雖然以上方法確實(shí)可行,但是卻并不是最優(yōu)的方案,并且還會(huì)重復(fù)保存頂點(diǎn)(以上方法共需要保存6個(gè)頂點(diǎn),其中第一個(gè)三角形的左下、右下點(diǎn)與第二個(gè)三角形的左上、右上點(diǎn)重疊)。實(shí)際上我們可以使用trianglestrips(GL_TRIANGLE_STRIP)方法通過(guò)四個(gè)頂點(diǎn)來(lái)繪制正方形。簡(jiǎn)單繪圖-四邊形51三角形條的基本概念:第一個(gè)三角形條是由前三個(gè)頂點(diǎn)構(gòu)成(索引0,1,2)。第二個(gè)三角形條是由前一個(gè)三角形的兩個(gè)頂點(diǎn)加上數(shù)組中的下一個(gè)頂點(diǎn)構(gòu)成,繼續(xù)直到整個(gè)數(shù)組結(jié)束??聪聢D更清楚–第一個(gè)三角形由頂點(diǎn)1,2,3構(gòu)成,下一個(gè)三角形由頂點(diǎn)2,3,4構(gòu)成,等等:簡(jiǎn)單繪圖-四邊形52所以,四邊形是這樣構(gòu)成的:通過(guò)提交的頂點(diǎn)數(shù)組來(lái)繪制四邊形
簡(jiǎn)單繪圖-四邊形//正方形的4個(gè)頂點(diǎn)
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著色有平滑著色、單調(diào)著色簡(jiǎn)單繪圖-彩色渲染平滑著色單調(diào)著色54單調(diào)著色設(shè)置當(dāng)前所使用的顏色設(shè)置了當(dāng)前顏色之后的所繪制的所有顏色都使用當(dāng)前顏色。簡(jiǎn)單繪圖-彩色渲染//設(shè)置當(dāng)前色為紅色
gl.glColor4f(1.0f,0.0f,0.0f,1.0f);55平滑著色OpenGLES允許將每個(gè)頂點(diǎn)使用的顏色置于一個(gè)顏色數(shù)組(colorarray)中。如果選擇使用顏色數(shù)組,那么需要為每個(gè)頂點(diǎn)設(shè)置顏色。
三個(gè)頂點(diǎn),每個(gè)頂點(diǎn)四個(gè)值簡(jiǎn)單繪圖-彩色渲染//三角形的頂點(diǎn)顏色值(r,g,b,a)
privateIntBuffercolorBuffer=IntBuffer.wrap(new
int[]{
one,0,0,one,0,one,0,one,0,0,one,one,});56平滑著色開(kāi)啟顏色渲染功能為三角形設(shè)置定義好的顏色關(guān)閉顏色渲染功能簡(jiǎn)單繪圖-彩色渲染//設(shè)置顏色數(shù)組gl.glEnableClientState(GL10.GL_COLOR_ARRAY);gl.glColorPointer(4,GL10.GL_FIXED,0,colorBuffer);gl.glDisableClientState(GL10.GL_COLOR_ARRAY);57繞某軸旋轉(zhuǎn)定義旋轉(zhuǎn)角度變量在onDrawFrame里設(shè)置旋轉(zhuǎn)publicabstractvoidglRotatef(floatangle,floatx,floaty,floatz)Angle定義了旋轉(zhuǎn)的角度
x,y,z共同決定了旋轉(zhuǎn)軸的方向改變旋轉(zhuǎn)角度簡(jiǎn)單繪圖-旋轉(zhuǎn)float
rotate;gl.glRotatef(rotate,0.0f,1.0f,0.0f);
//繞y軸rotate
-=0.5f;58例:繪制一個(gè)四棱錐與繪制三角形相似,重點(diǎn)都在于構(gòu)建頂點(diǎn)坐標(biāo)構(gòu)建頂點(diǎn)坐標(biāo)時(shí),需要按照逆時(shí)針的方向來(lái)繪制(WHY?按照順時(shí)針繪制會(huì)怎么樣?)簡(jiǎn)單繪圖-3D空間59四棱錐由四個(gè)三角形組成簡(jiǎn)單繪圖-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使用循環(huán)把四個(gè)面都繪制出來(lái)簡(jiǎn)單繪圖-3D空間//繪制四棱錐
for(inti=0;i<4;i++){gl.glDrawArrays(GL10.GL_TRIANGLE,i*3,3);}61OpenGLES中具有的兩種不同的視口類(lèi)型。正交(orthogonal)透視(perspective)OpenGL---透視62正交視線(xiàn)永遠(yuǎn)不會(huì)交匯而且物體不會(huì)改變其大小。沒(méi)有透視效果。
OpenGL---透視63透視
物體會(huì)隨著移遠(yuǎn)而越來(lái)越小,視線(xiàn)會(huì)在物體移離觀(guān)察者時(shí)最終交匯。這是對(duì)真實(shí)視覺(jué)的模擬,人們就是以這種方式觀(guān)察世界的。OpenGL---透視64rightneartopOpenGL---透視65設(shè)置正交視口通過(guò)glOrthof()通知OpenGLES你希望使用正交視口OpenGL---透視
floatratio=_width/_height;//屏幕寬長(zhǎng)比//orthographic:gl.glOrthof(-1,//left1,//right-1/ratio,//bottom1/ratio,//top0.01f,//near100.0f);//far設(shè)定視口空間的寬度為兩個(gè)單位,沿x軸從-1.0到+1.0。
定義空間的X和Y坐標(biāo)的寬高比與視窗的寬高比(也就是全屏?xí)r的寬高比)一樣,確保視口的X和Y坐標(biāo)遵循一樣的比例。
66near
參數(shù):說(shuō)明了視口開(kāi)始的位置。如果我們站在原點(diǎn)處,視口就位于我們的面前,習(xí)慣上使用.01
或.001
作為正交視口的起點(diǎn)。使得視口處于原點(diǎn)“前方”一點(diǎn)點(diǎn)。
far描述觀(guān)察的深度,根據(jù)你程序的需要來(lái)設(shè)定。設(shè)置正交視口定義了near(遠(yuǎn))和far(近)范圍來(lái)描述觀(guān)察的深度。OpenGL---透視floatratio=_width/_height;//屏幕長(zhǎng)寬比//orthographic:gl.glOrthof(-1,//left1,//right-1/ratio,//bottom1/ratio,//top0.01f,//near100.0f);//far67調(diào)用glOrthof()之后,我們使用視窗矩形來(lái)調(diào)用glViewport()。
切換了MatrixMode到GL10.GL_MODELVIEW,設(shè)置OpenGL接受關(guān)于改變model繪制方式的調(diào)用。
OpenGL---透視
gl.glViewport(0,0,(int)_width,(int)_height);68調(diào)用了glEnable()并使用參數(shù)GL10.GL_DEPTH_TEST。使OpenGLES檢查對(duì)象的z方向的順序。如果我們沒(méi)有enable它,我們將看到最后被繪制的對(duì)象一直顯示在最前面。這意味著,即使這個(gè)物體本來(lái)應(yīng)該被更近更大的物體遮蓋,我們依然可以看到它。
OpenGL---透視
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glEnable(GL10.GL_DEPTH_TEST);69設(shè)置透視視口隨著視線(xiàn)越來(lái)越遠(yuǎn),可以看到更廣闊的世界物體隨著遠(yuǎn)離觀(guān)察者而變小使用透視時(shí)可見(jiàn)空間的形狀稱(chēng)為錐臺(tái)(frustum)OpenGL---透視70視野(fieldofvision)
由兩個(gè)角度定義的:伸出雙臂手掌合攏伸向前方。你的手臂現(xiàn)在指向你自己錐臺(tái)的z軸?,F(xiàn)在慢慢分開(kāi)你的雙臂,定義了一個(gè)逐漸增大的角度。這就是用于定義觀(guān)察錐臺(tái)的兩個(gè)角度之一,它定義了視野的寬度。OpenGL---透視71視野(fieldofvision)
上下展開(kāi)你的雙臂,定義了另一個(gè)角度。如果你的雙手間距只有三厘米,那么角度將非常小。這稱(chēng)為窄視野。如果你雙手分開(kāi)兩米,視野的寬度變得很大。這就是所謂寬視角(廣角)。OpenGL---透視72設(shè)置透視視口我們選擇一個(gè)中間值,45°。使用這個(gè)值,我們?cè)鯓佑?jì)算我們的觀(guān)察錐臺(tái)?想象一下,從頂部看錐臺(tái)是什么樣子。OpenGL---透視45°
下面是示意圖:
73設(shè)置透視視口正切函數(shù)定義為直角對(duì)邊與相鄰邊的比率。
錐臺(tái)遠(yuǎn)端寬度的一半就是視野角度正切的一半。將此值乘以near值,就可以得到right值。
right值取反就是left。OpenGL---透視nearright(45/2)°right=near*tan(45/2)74設(shè)置透視視口通過(guò)glFrustumf()通知OpenGLES你希望使用正交視口OpenGL---透視
floatsize=0.01f*(float)Math.tan(Math.toRadians(45.0)/2);
floatratio=_width/_height;//屏幕長(zhǎng)寬比//perspective:gl.glFrustumf(-size,//leftsize,//right
-size/ratio,//bottomsize/ratio,//top0.01f,//near100.0f);//farsize=near*tan(45/2),為左右視野的寬度定義空間的X和Y坐標(biāo)的寬高比與視窗的寬高比(也就是全屏?xí)r的寬高比)一樣,確保視口的X和Y坐標(biāo)遵循一樣的比例。
rightneartop75OpenGL---透視透視效果隨著幾何體遠(yuǎn)離你,它們會(huì)變得越來(lái)越小,正像火車(chē)鐵軌一樣。正交效果第一個(gè)四棱錐后面的四棱錐完全被第一個(gè)擋住了。因?yàn)闆](méi)有透視,后面的各幾何體的形狀完全取決于其前方的物體。
76OpenGL在沒(méi)有設(shè)置光效的情況下仍然可以看見(jiàn)東西。它只是提供一種十分單調(diào)的整體光讓我們看到物體。但是如果不定義光效,物體看上去都很單調(diào)。OpenGL---光效77OpenGLES實(shí)際上定義了兩種shademodel,GL_FLAT
和GL_SMOOTH。
GL_FLAT將指定三角形上的每個(gè)像素都同等對(duì)待。多邊形上的每個(gè)像素都具有相同的顏色,陰影等。它的計(jì)算比每個(gè)像素按不同方法計(jì)算更為廉價(jià),但是在這種方式下,物體看上去極為不真實(shí)。
OpenGL---光效78要使3D物體盡量真實(shí),應(yīng)該使用GL_SMOOTH
繪圖模式,它使用了一種平滑但較快速的陰影算法,稱(chēng)為Gouraud算法。GL_SMOOTH是默認(rèn)值。
OpenGL---光效79首先啟動(dòng)光效。默認(rèn)情況下,手工指定光效是被禁止的。通常情況下,光效只需在設(shè)定時(shí)啟動(dòng)一次。不需要在繪圖開(kāi)始前后打開(kāi)和關(guān)閉。啟動(dòng)光效后的效果:
OpenGL---光效//如果不啟用GL_LIGHTING光就什么都看不見(jiàn)gl.glEnable(GL10.GL_LIGHTING);80啟動(dòng)了光效,但是沒(méi)有創(chuàng)建任何光源。除清除緩存用的灰色外,任何繪制的物體都被渲染成絕對(duì)的黑色。如果只對(duì)光源進(jìn)行設(shè)置、定位甚至啟用,光源不會(huì)工作,除非啟用GL_LIGHTING。OpenGLES允許你創(chuàng)建8個(gè)光源。有一個(gè)常量對(duì)應(yīng)于這些光源中的一個(gè),常量為GL_LIGHT0
到GL_LIGHT7??梢匀我饨M合這些光源中的五個(gè)。下面是“打開(kāi)”第一個(gè)光源GL_LIGHT1的方法:OpenGL---光效gl.glEnable(GL10.GL_LIGHT1);//啟用一號(hào)光源81一旦啟動(dòng)了光源,則必須設(shè)置光源的一些屬性。一般情況下,有三個(gè)不同的要素用來(lái)定義光源。光效三要素在OpenGLES中,光由三個(gè)元素組成:
環(huán)境元素(ambientcomponent)散射元素(diffusecomponent)高光元素(specularcomponent)OpenGL---光效82高光元素(specularcomponent)定義了光線(xiàn)直接照射并反射到觀(guān)察者從而形成了物體上的“熱點(diǎn)”或光澤。光點(diǎn)的大小取決于一些因素,但是如果你看到如上圖黃球所示一個(gè)區(qū)域明顯的光斑,那通常就是來(lái)自于一個(gè)或多個(gè)光源的高光部分。散射元素(diffusecomponent)定義了比較平均的定向光源,在物體面向光線(xiàn)的一面具有光澤。
環(huán)境光(ambientcomponent)沒(méi)有明顯的光源。其光線(xiàn)折射與許多物體,因此無(wú)法確定其來(lái)源。環(huán)境元素平均作用于場(chǎng)景中的所有物體的所有面。OpenGL---光效83環(huán)境光(ambient)光效中有越多的環(huán)境元素,就越不會(huì)產(chǎn)生引入注目的效果。場(chǎng)景中的總環(huán)境光效是由所有啟動(dòng)光源的環(huán)境光組合在一起所決定的。如果你使用了
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度地基資源買(mǎi)賣(mài)合同協(xié)議3篇
- 概率論課程設(shè)計(jì)小標(biāo)題
- 2024-2025學(xué)年度山東省德州市臨邑博文中學(xué)高一第一學(xué)期第三次月考?xì)v史試題
- 英語(yǔ)學(xué)科的課程設(shè)計(jì)方案
- 猜音符課程設(shè)計(jì)
- 網(wǎng)站課程設(shè)計(jì)收獲總結(jié)
- 班級(jí)班長(zhǎng)培訓(xùn)課程設(shè)計(jì)
- 穩(wěn)壓器課程設(shè)計(jì)
- 英語(yǔ)交際用語(yǔ)課程設(shè)計(jì)
- 教輔行業(yè)助理的工作總結(jié)和技能要求
- 手動(dòng)及手持電動(dòng)工具培訓(xùn)考核試卷
- 2024年湖北省公務(wù)員錄用考試《行測(cè)》真題及答案解析
- 自然辯證法習(xí)題及答案
- 特色農(nóng)產(chǎn)品超市方案
- 2024國(guó)有企業(yè)與民營(yíng)企業(yè)之間的混合所有制改革合同
- 2024年醫(yī)院食堂餐飲獨(dú)家承包協(xié)議
- 保險(xiǎn)公司廉政風(fēng)險(xiǎn)防控制度
- DB34T4868-2024智慧醫(yī)院醫(yī)用耗材院內(nèi)物流規(guī)范
- 2025年蛇年年會(huì)匯報(bào)年終總結(jié)大會(huì)模板
- 《稻草人》閱讀題及答案
- 國(guó)家職業(yè)技術(shù)技能標(biāo)準(zhǔn) X2-10-07-17 陶瓷產(chǎn)品設(shè)計(jì)師(試行)勞社廳發(fā)200633號(hào)
評(píng)論
0/150
提交評(píng)論