鯤鵬it教育android課件游戲開發(fā)項目_第1頁
鯤鵬it教育android課件游戲開發(fā)項目_第2頁
鯤鵬it教育android課件游戲開發(fā)項目_第3頁
鯤鵬it教育android課件游戲開發(fā)項目_第4頁
鯤鵬it教育android課件游戲開發(fā)項目_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Android游戲開發(fā)OpenGL開發(fā)基礎(chǔ)框架繪制立體圖形課程安排三角形的頂點法和索引法渲染流水線福特怎樣組裝汽車?流水線是將一個重復(fù)的過程分為若干個子過程,每個子過程可以和其他子過程并行運作。渲染流水線與此類似,只是圖形渲染替代了汽車生產(chǎn)。實質(zhì)上是圖形芯片內(nèi)部處理圖形信號相互獨立的并行處理單元。圖形數(shù)據(jù)(頂點,點段,三角面)從流水線的開端輸入經(jīng)過流水線的各個階段圖元處理:計算頂點坐標和顏色頂點緩沖:將頂點數(shù)據(jù)放入內(nèi)存或顯存,使用java.nio變換與光照:變換包括視口變換、投影變換、模型變換等。根據(jù)光源、材質(zhì)、位置等信息計算出光照情況。圖元裝配:所有圖形基礎(chǔ)數(shù)據(jù)進行組裝光柵化:對三維空間進行拍照,使之成為二維像素集合霧化:處理模糊、銳化、煙等特效Alpha測試:當Alpha值滿足某特定條件時才會被渲染出來。如設(shè)置glAlphaFunc(GL_EQUAL,0.0f)是只顯示Alpha=0(完全不透明)的區(qū)域,透明區(qū)域?qū)⒈粍h除。GL_ALWAYS、GL_EQUAL、GL_NEVER、GL_GEQUAL、GL_LESS、GL_NOTEQUAL、GL_LEQUAL深度測試:檢測Z值。模板測試:根據(jù)三角面上的顯示標記進行特殊處理。這些標記稱為模板緩沖區(qū)。顏色混合:將三角面的顏色與設(shè)定顏色進行混合。圖像抖動:是一種在可用顏色數(shù)量較少的系統(tǒng)中,使用的利用人眼色差產(chǎn)生豐富顏色的技巧。初始化OpenGLESGLInitActivity:程序主入口GLRender:渲染場景MySurfaceView:獲取用戶輸入,實現(xiàn)人機交互。publicclassGLInitActivityextendsActivity{@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);

MySurfaceViewmySurfaceView=newMySurfaceView(this);

setContentView(mySurfaceView);}}初始化OpenGLES要先創(chuàng)建一個GLRenderer對象,然后在構(gòu)成中調(diào)用sendRenderer()設(shè)置渲染對象。重寫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負責(zé)場景渲染,有三個比較重要的方法:onSurfaceCreated(),onDrawFrame()和onSurfaceChanged()方法。onSurfaceCreated():場景創(chuàng)建時的操作,例如圖形數(shù)據(jù)的創(chuàng)建,光照對象的設(shè)置。onDrawFrame()用于場景繪制時的操作,例如變換,實現(xiàn)動畫。onSurfaceChanged()用于屏幕發(fā)生變化時的操作,例如屏幕旋轉(zhuǎn)、視口發(fā)生變化。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);//清除深度緩沖數(shù)據(jù)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;//設(shè)置OpenGL視口gl.glViewport(0,0,width,height);//設(shè)置透視投影矩陣gl.glMatrixMode(GL10.GL_PROJECTION);//單位化投影矩陣gl.glLoadIdentity();//設(shè)置視口的大小gl.glFrustumf(-ratio,ratio,-1,1,1,10);//選擇模型觀察矩陣gl.glMatrixMode(GL10.GL_MODELVIEW);//單位化觀察矩陣gl.glLoadIdentity();}解釋glShadeModel函數(shù)用于控制opengl中繪制指定兩點間其他點顏色的過渡模式。參數(shù)一般為GL_SMOOTH(默認),GL_FLAT。opengl默認是將制定的兩點顏色進行插值,繪制之間的其他點。如果兩點的顏色相同,使用兩個參數(shù)效果相同。如果兩點顏色不同,GL_SMOOTH會出現(xiàn)過渡效果,GL_FLAT則只是以指定的某一點的單一色繪制其他所有點。當您調(diào)用glLoadIdentity()之后,您實際上將當前點移到了屏幕中心,X坐標軸從左至右,Y坐標軸從下至上,Z坐標軸從里至外。OpenGL屏幕中心的坐標值是X和Y軸上的0.0f點。中心左面的坐標值是負值,右面是正值。移向屏幕頂端是正值,移向屏幕底端是負值。移入屏幕深處是負值,移出屏幕則是正值。在Android系統(tǒng)中,使用OpenGLES的作用是構(gòu)建三維效果。在OpenGLES中,三維效果都是通過構(gòu)建三角形實現(xiàn)的。在OpenGL中有兩個比較重要的投影變換函數(shù),glViewport和glOrtho。glOrtho是創(chuàng)建一個正交平行的視景體。一般用于物體不會因為離屏幕的遠近而產(chǎn)生大小的變換的情況。比如,常用的工程中的制圖等。需要比較精確的顯示。而作為它的對立情況,glFrustum則產(chǎn)生一個透視投影。這是一種模擬真是生活中,人們視野觀測物體的真實情況。例如:觀察兩條平行的火車到,在過了很遠之后,這兩條鐵軌是會相交于一處的。還有,離眼睛近的物體看起來大一些,遠的物體看起來小一些。glOrtho(left,right,bottom,top,near,far),left表示視景體左面的坐標,right表示右面的坐標,bottom表示下面的,top表示上面的。這個函數(shù)簡單理解起來,就是一個物體擺在那里,你怎么去截取他。這里,我們先拋開glViewport函數(shù)不看。先單獨理解glOrtho的功能。假設(shè)有一個球體,半徑為1,圓心在(0,0,0),那么,我們設(shè)定glOrtho(-1.5,1.5,-1.5,1.5,-10,10);就表示用一個寬高都是3的框框把這個球體整個都裝了進來。如果設(shè)定glOrtho(0.0,1.5,-1.5,1.5,-10,10);就表示用一個寬是1.5,高是3的框框把整個球體的右面裝進來;如果設(shè)定glOrtho(0.0,1.5,0.0,1.5,-10,10);就表示用一個寬和高都是1.5的框框把球體的右上角裝了進來。上述三種情況可以見圖:glOrtho函數(shù)只是負責(zé)使用什么樣的視景體來截取圖像,并不負責(zé)使用某種規(guī)則把圖像呈現(xiàn)在屏幕上。glViewport主要完成這樣的功能。它負責(zé)把視景體截取的圖像按照怎樣的高和寬顯示到屏幕上。緩沖變換//獲取整形緩沖數(shù)據(jù)publicIntBuffergetIntBuffer(int[]vertexes){IntBufferbuffer;ByteBufferqbb=ByteBuffer.allocateDirect(vertexes.length*4);qbb.order(ByteOrder.nativeOrder());

buffer=qbb.asIntBuffer();buffer.put(vertexes);buffer.position(0);returnbuffer;}//獲取字節(jié)型緩沖數(shù)據(jù)publicByteBuffergetByteBuffer(byte[]vertexes){ByteBufferbuffer=null;buffer=ByteBuffer.allocateDirect(vertexes.length);buffer.put(vertexes);buffer.position(0);returnbuffer;}頂點法繪制三角形OpenGLES向我們提供了兩種繪制三角面的方法,一種是頂點法,一種是索引法?,F(xiàn)在要畫一個簡單的矩形面。我們首先需要向OpenGLES的繪制流水線指定一個頂點緩沖,緩沖中記錄了各個頂點的坐標數(shù)據(jù),渲染的時候OpenGLES將會從緩沖中依次讀取各個頂點的數(shù)據(jù)并且依次連接填充為三角面。例如構(gòu)成一個簡單的矩形平面我們至少需要兩個三角面。需要六組頂點數(shù)據(jù)。第一步,需要在GLRender類中定義FloatBuffer頂點緩沖。私有全局變量。第二步,需要在OnSurfaceCreated中創(chuàng)建圖形數(shù)據(jù),定義一個vertexs坐標數(shù)組。調(diào)用getFloatBuffer()方法將vertexts數(shù)據(jù)寫入頂點緩沖。//定義頂點緩沖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;//創(chuàng)建頂點緩沖

this._vertexsBuffer=Util.getFloatBuffer(vertexs);//告訴系統(tǒng)對透視進行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);//定義頂點數(shù)據(jù)

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()方法中實現(xiàn)對兩個三角面的渲染繪制。需要調(diào)用glVertextPointer()為繪制流水線指定頂點緩沖。調(diào)用glDrawArrays()告訴OpenGLES繪制流水線用頂點法。調(diào)用glDisableClientState()關(guān)閉頂點緩沖。

//移入屏幕一段距離

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

//設(shè)置3個方向的旋轉(zhuǎn)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);//允許設(shè)置頂點gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

gl.glVertexPointer(3,GL10.GL_FLOAT,0,this._vertexsBuffer);gl.glDrawArrays(GL10.GL_TRIANGLES,0,6);//取消頂點設(shè)置

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//結(jié)束繪制

gl.glFinish();索引法繪制三角形索引法仍然是用GL_TRIANGLES繪制三角面。相比頂點法我們只需要四組的頂點數(shù)據(jù),還需要指定一個索引緩沖,索引緩沖描述了頂點繪制的序列。第一步,定義FloatBuffer頂點緩沖和ByteBuffer索引緩沖。第二步,定義長度12的頂點數(shù)組,創(chuàng)建byte數(shù)組,代表v0-v1-v2和v0-v2-v3,因此數(shù)組長度為6。調(diào)用getFloatBuffer()和getByteBuffer()//定義頂點緩沖privateFloatBuffer_vertexsBuffer;//定義索引緩沖privateByteBuffer_indicesBuffer;vertexs[9]=1.0f;vertexs[10]=-1.0f;vertexs[11]=0.0f;//創(chuàng)建索引數(shù)據(jù)

byteindices[]=newbyte[6];

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

//創(chuàng)建頂點緩沖

this._vertexsBuffer=Util.getFloatBuffer(vertexs);

//創(chuàng)建索引緩沖

this._indicesBuffer=Util.getByteBuffer(indices);//創(chuàng)建頂點數(shù)據(jù)

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()方法中實現(xiàn)對兩個三角面的渲染繪制。需要調(diào)用glVertextPointer()為繪制流水線指定頂點緩沖。調(diào)用glDrawElements()以索引法繪制。

//移入屏幕一段距離

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

//設(shè)置3個方向的旋轉(zhuǎn)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);//允許設(shè)置頂點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);//取消頂點設(shè)置

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//結(jié)束繪制

gl.glFinish();更多的繪制模式除了GL_TRAINGLES的方式,還支持以下的繪制方式:GL_POINTS根據(jù)頂點緩沖的坐標按順序繪制頂點。GL_LINES頂點緩沖坐標數(shù)據(jù)兩兩成對,每兩個頂點胡坐標數(shù)據(jù)成一組。GL_LINE_STRIF頂點緩沖中的坐標前后成對。GL_LINE_LOOP與GL_LINE_STRIF類似,但把第一個和最后一個相連。GL_TRIANGLES頂點緩沖中的每三個坐標數(shù)據(jù)為一組,同組的三個頂點將首尾相連成一個封閉的三角。每三個頂點數(shù)據(jù)獨立成組,不用另外的三角共享頂點。GL_TRIANGLE_STRIP三角形帶繪制模式。共享頂點。GL_TRIANGLE_FAN三角扇形繪制。以第一個頂點為中心,依次推進形成一個扇形狀三角。使用GL_TRIANGLES能夠繪制出任何形狀,但是用GL_TRIANGLE_STRIP和GL_TIANGLE_FAN有時能減少頂點數(shù)量,提高渲染速度。繪制平面平面是許多復(fù)雜立體幾何體的基本組成,也是許多三維立體對象的承載體。步驟:第一步,需要設(shè)定一個原點。第二步,根據(jù)長寬確定邊界。第三步,根據(jù)行列缺定二維網(wǎng)格數(shù)據(jù)以及細分反案,從而劃分出若干個三角面。第四步,將所有三角面的頂點數(shù)據(jù)依次寫入頂點緩沖。第五步,渲染所有三角面。Vertex3f類便于頂點數(shù)據(jù)的創(chuàng)建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;//行數(shù)privateint_column=10;//列數(shù)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;//創(chuàng)建圖形數(shù)據(jù)this.createGraphics();}繪制平面createGraphics()方法用于圖形頂點數(shù)據(jù)的創(chuàng)建,draw()進行繪制在GLRender類中創(chuàng)建一個RectanglePlane類型的矩形平面對象,并傳入相關(guān)參數(shù)。給場景添加光照。privatevoidcreateGraphics(){//設(shè)置原點Vertex3fpos=newVertex3f(0.0f,0.0f,0.0f);

//設(shè)置網(wǎng)格頂點

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);}}

//設(shè)置三角形頂點

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;}}//設(shè)置頂點緩沖

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類中創(chuàng)建一個RectanglePlane類型的矩形平面對象,并傳入相關(guān)參數(shù)。給場景添加光照。publicvoiddraw(GL10gl){//允許設(shè)置頂點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);//取消頂點設(shè)置

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//繪制結(jié)束

gl.glFinish();}privateRectanglePlane_rectanglePlane=newRectanglePlane(10.0f,10.0f,10,10);//定義環(huán)境光(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//設(shè)置環(huán)境光

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

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

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);//設(shè)置3個方向的旋轉(zhuǎn)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);圓形平面圓形平面在需要模擬地平線的時候能派上用場。第一步,設(shè)定原點,根據(jù)設(shè)定的長度半徑確定邊界。第二步,根據(jù)設(shè)定的行列數(shù),確定一個二維網(wǎng)格數(shù)據(jù),以行為單位,把同行的頂點數(shù)據(jù)進行旋轉(zhuǎn)變換,從而組成一個閉合的圓形(繞Y軸進行旋轉(zhuǎn)變換),圓形的半徑隨行數(shù)遞減直至圓心位置。第三步,根據(jù)網(wǎng)格數(shù)據(jù)將網(wǎng)格細分為若干個三角形。第四步,將所有三角形的頂點依次寫入頂點緩沖。第五步,渲染所有三角形面。創(chuàng)建一個CirclePlane類用于圓形平面的繪制。也要創(chuàng)建一個Vertex3f數(shù)組。publicclassCirclePlane{privateint_row=10;//行數(shù)privateint_column=20;//列數(shù)privatefloat_radius=5.0f;//半徑privateFloatBuffer_planeBuffer;publicCirclePlane(floatradius,introw,intcolumn){this._radius=radius;this._row=row;this._column=column;//創(chuàng)建圖形數(shù)據(jù)this.createGraphics();}//設(shè)置網(wǎng)格頂點

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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論