OpenGL(open graphics library)
Open GL 于 Open GL ES 之間的關系,,OpenGL ES 是專為内嵌和移動裝置設計的一個2D/3D的一個輕量級圖形庫,,它是基于OpenGL API設計的,,,是OpenGL三維圖形API的子集,針對手機,PDA和遊戲主機等嵌入式裝置設計的。。。在這裡隻介紹OpenGL 的一個簡單入門,,因為OpenGL内容太豐富了,,,有興趣的可深入研究。。。
1,基本架構搭建
Android中為我們提供了GLSurfaceView來非常好的現實OpenGL試圖,而GLSurfaceView中則包含了一個專門用于渲染3D的接口,,Renderer,,是以這裡我們先來建構一個子集的Renderer類
當視窗被建立需要調用onSurfaceCreated,是以我們可以在裡面對OpenGL做一些初始化工作,例如:public class MyRenderer implements Renderer{ } //在MyRenderer中我們必須實作3個Renderer定義的3個方法,,,, public void onDrawFrame(GL10 gl){ } public void onSurfaceChanged(GL10 gl,int width,int lenght){ } public void onSurfaceCreated(GL10 gl,EGLConfig config){ }
//告訴系統對透視進行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST); //黑色背景 gl.glClearColor(0,0,0,0); //啟用陰影平滑 gl.glShadeModel(GL10.GL_SMOOTH);
其中,glHint告訴OpenGL我們希望進行最好的透視修正,,這樣可能稍微影響性能,但會使我們的試圖效果看起來品質更高一點,,glClearColor設定清楚螢幕所用的顔色,色彩值的範圍從0.0f-1.0f,,,0.0f代表最黑的情況,,這可能和我們以前所使用顔色取值範圍不太一樣。。方法中的4個參數分别(red ,green,,blue,,alpha),,範圍都是0.1f到1.0f。。。(0,0,0,0)也就是黑色,,(1,1,1,1)也就是白色。。glShadeModel用于啟動smooth shading(陰影平滑)。陰影平滑通過對多變型精細的混合色彩,并對外部光進行平滑。。
接下來我們還需要做的是一個最重要的步驟是關于depth buffer (深度緩存)的,将深度緩存攝像為螢幕後面的層,,它不斷的對物體進入螢幕内部的深度進行跟蹤。它的排序決定哪個物體先畫,這樣我們就不會将一個圓形後面的正方形畫到圓形的線面去,,,深度緩存是OpenGL十分重要的部分,,
當視窗的大小發生改變時會調用onSurfaceChanged方法,但是,不管視窗的大小是否已經改變,他在程式開始時至少會運作一次,,是以我們在該方法中設定OpenGL場景的大小,這裡将OpenGL場景設定成他顯示所在的視窗的大小,,,//設定深度緩存 gl.glClearDepthf(1.0f); //啟動深度測試 gl.glEnable(GL10.GL_DEPTH_TEST); //所作深度測試的類型 gl.glDepthFunc(GL10.GL_LEQUAL);
最後隻需要調用GLSurfaceView類得setRenderer方法将我們自己的Renderer類設定為預設的Renderer即可//設定OpenGL場景的大小 gl.glViewport(0,0,width,height); //設定投影矩陣 gl.glMatrixMode(GL10.GL_PROJECTION); //指明接下來的代碼将影響 projection matrix(投影矩陣),投影矩陣是負責給場景增加透視的 //重置投影矩陣 gl.glLoadIdentity(); //調用之後為場景設定透視圖 //設定視口的大小 gl.glFrustumf(-ratio,ratio,-1,1,1,10); //前面4個參數用于确定視窗的大小,後面兩個參數分别是在場景中所能繪制深度的起點和終點 //最後,,,所有的繪圖操作都在onDrawFrame方法中進行,在繪圖之前,需要将螢幕清楚成前面所指定的顔色,清楚深度緩存并且重置場景,然後就可以進行繪圖了//,, //清楚螢幕和深度緩存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);gl.glLoadIdentity();
這些都是最基本得内容,但也是最重要的,,接着我們就可以在這個架構上面來進行開發了。。。Renderer render = new MyRenderer(); GLSurfaceView glView = new GLSurfaceView(this); glView.setRenderer(render); this.setContentView(glView);
2,多邊形
在openGL中繪制的任何模型都會被分解為三角形和四邊形這兩種簡單的圖形,是以我們首先要用openGL來繪制一個三角形和一個四邊形,我們現在隻需要在MyRenderer中的onDrawFrame中添加繪制代碼即可,但是,我們在這之前需要了解一下openGL中的坐标系,當調glLoadIdentity()之後,實際上市将目前點移動到了螢幕中心,X軸從左到右,Y軸從下到上,Z軸從裡到外,,跟我們應用程式中坐标系還有最大的一個差別是,他的中心點,也就是0.0f點是在螢幕中心的,,,在我們android應用中layout的0.0f點是在螢幕的左上角。。
我們都知道三角形由3個頂點組成,是以需要先定義出三角形和四邊形的頂點坐标,這裡的三角形不再處于2D平面中,而是在3D空間中,是以每一個坐标點都是有(x,y,z)構成,比如一個三角形的頂點數組如下:
int one = 0x10000; //三角形三個頂點 private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{ 0,one,0, //上頂點 -one,-one,0, //左下點 one,-one,0}); //右下點
四邊形的頂點數組當然就是由4個頂點組成的了,,這裡需要在左邊繪制一個三角形,在右邊繪制一個四邊形,,是以需要用glTranslatef(X,Y,Z)将目前的重點移至要繪制三角形的位置,,
gl.glTranslatef(-1.5f,0.0f,-6.0f); //沿着X軸左移1.5個機關,,Y軸不動,最後Z軸向内移動6.0f個機關。。。。。。
現在已經移動到了螢幕的作伴部分,并将試圖推入螢幕背後足夠的距離以便可以看見全部的場景,這裡需要注意的是螢幕内移動的機關必須小于通過glFrustumf方法所設定的最遠距離,否則顯示不出來,,。。。我們為openGL設定一個頂點數組,是以需要告訴openGL要設定頂點這個功能:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //gl.glVertexPointer(int size,int type,int stride,Buffer pointer)設定頂點資料,,size用于描述頂點的尺寸,type描述了頂點的類型,stride描述了補償,pointer是頂點緩存,也就是我們建立///的頂點數組 gl.glVertexPointer(3,GL10.GL_FIXED,0,triggerBuffer);
接下來我們就可以通過glDrawArrays(int mode,int first,int count)方法将這些頂點繪制出來,參數mode描述了繪制的模式,我們使用GL_TRIANGLES來表示繪制三角形,後面兩個參數分别是開始位置和要繪制的頂點計數
gl.glDrawArrays(GL10,GL_TRIANGLES,0,3);
三角形繪制完成,,,四邊形同理。。。。。
!!! 今天太瞌睡了,,關于圖形着色和旋轉,以及紋理貼下次描述public void onDrawFrame(GL10 gl){ //清楚螢幕和深度緩存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); //重置目前的模型觀察矩陣 gl.glLoadIdentity(); //左移1.5機關,并移入螢幕6.0f gl.glTranslatef(-1.5f, 0.0f, -6.0f); //允許設定頂點 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //設定三角形 gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer); //繪制三角形 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); //重置目前的模型觀察矩陣 gl.glLoadIdentity(); //右移1.5機關,并移入螢幕6.0f gl.glTranslatef(-1.5f, 0.0f, -6.0f); //設定和繪制四邊形 gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //取消頂點設定 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); }