Android OpenGL ES學習筆記之繪製點

一、一些基本概念

世界座標系

世界座標系就是3D繪圖中像素的座標。在3D繪圖中,座標軸遵循右手法則,讓你右手手心正對自己,大拇指指向X軸正方向,拇指指向Y軸正方向,中指指向Z軸正方向。如下圖所示

這裏寫圖片描述

點的表示

空間中一個點具有(x,y,z)座標。在Android系統中,可以用一個float數組、int數組等來表示一個點,比如

private float[] mArray = { 0f, 0f, 0f };

而在OpenGl ES中,爲了提高性能,會把點、顏色等數組放在java.nio 包中定義的Buffer類中。類似於IO流中的緩衝。

創建一個工具類Utils,把獲取Buffer數據的代碼封裝下

public class Utils {     
    /**
     * @param vertexs float 數組
     * @return 獲取浮點形緩衝數據
     */
    public static FloatBuffer getFloatBuffer(float[] vertexs) {
        FloatBuffer buffer;
        ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 4);
        qbb.order(ByteOrder.nativeOrder());
        buffer = qbb.asFloatBuffer();
        //寫入數組
        buffer.put(vertexs);
        //設置默認的讀取位置
        buffer.position(0);
        return buffer;
    }    
}

二、繪製一個點

這裏只貼上MyRenderer類的代碼,其餘代碼和之前搭建的基礎框架一樣。
我會逐一講解

public class MyRenderer implements GLSurfaceView.Renderer {
        //頂點數組
        private float[] mArray = { 0f, 0f, 0f };

        // 緩衝區
        private FloatBuffer mBuffer;

        public MyRenderer() {
            //獲取浮點形緩衝數據
            mBuffer = Utils.getFloatBuffer(mArray);
        }

        // Surface創建的時候調用
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // 設置清屏顏色爲黑色
            gl.glClearColor(0f, 0f, 0f, 0f);
        }

        // Surface改變的的時候調用
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            // 設置窗口大小
            gl.glViewport(width / 4, width / 2, width / 2, height / 2);
        }

        // 在Surface上繪製的時候調用
        @Override
        public void onDrawFrame(GL10 gl) {

            // 清除屏幕 
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

            // 允許設置頂點 // GL10.GL_VERTEX_ARRAY頂點數組
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

            // 設置頂點
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBuffer);

            //設置點的顏色爲綠色
            gl.glColor4f(0f, 1f, 0f, 0f);

            //設置點的大小
            gl.glPointSize(80f);

            // 繪製點
            gl.glDrawArrays(GL10.GL_POINTS, 0, 1);

            // 禁止頂點設置
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

        }
    }

1、定義頂點數組

我取了一個點的數組,定義x,y,z座標爲(0f,0f,0f)

2、獲取浮點形緩衝數據

傳入數組,獲取浮點形緩衝數據,這一段代碼是放在了構造函數裏

3、設置清屏顏色

onSurfaceCreated裏設置了清屏顏色爲黑色,這樣便於觀看。

glClearColor是設置清屏顏色,類似的還有

 - glClearDepthf——指明深度緩衝區的清理值

 - glClearStencil——指明模板緩衝區的清理值

通過調用步驟4裏的glClear方法清理。

glClearDepthf(float depth )指明的區間是0~1,初始值爲1
glClearStencil(int s)指明模板緩衝區的清理值

4、清除屏幕

glClear(int mask) 方法是用來清理緩衝區,並設置爲預設值。
mask的值有以下三種:

 - GL_COLOR_BUFFER_BIT——表明顏色緩衝區

 - GL_DEPTH_BUFFER_BIT——表明深度緩衝

 - GL_STENCIL_BUFFER_BIT——表明模型緩衝區

關於清除屏幕的這三種類型的用法,我會在後續單獨用一篇文章來講解。

5、允許設置頂點

glEnableClientState(int array) 調用這個方法來啓用客戶端的某項功能。對應的是glDisableClientState(int array) 禁用客戶端的某項功能。

默認情況下,所有功能是被禁止的。

根據傳遞進入的int參數選擇某項功能。
array 可以是下列符號常量:

 - GL_VERTEX_ARRAY ——如果啓用,頂點矩陣可以用來寫入

 - GL_COLOR_ARRAY————如果啓用,顏色矩陣可以用來寫入

 - GL_NORMAL_ARRAY—— 如果啓用,  法線矩陣可以用來寫入

 - GL_TEXTURE_COORD_ARRAY——如果啓用,紋理座標矩陣可以用來寫入

 - GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)——如果啓用,點大小矩陣控制大小以渲染點和點sprites。這時由glPointSize 定義的點大小將被忽略,由點大小矩陣提供的大小將被用來渲染點和點sprites。

以上幾種參數按順序對應的專業名詞是

 - 頂點
 - 顏色
 - 法線(用於光照處理)
 - 材質

PS:最後一個參數GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)我在GL10這個類裏沒找到,不知道爲什

後續會講到這些的用法。

6、設置頂點

glVertexPointer(int size, int type, int stride, Buffer pointer)是定義一個頂點座標矩陣。傳入四個參數

 - size——每個頂點的座標維數,必須是2, 3 或者4,初始值是4。

 - type——指明每個頂點座標的數據類型,允許的符號常量GL_BYTE, GL_SHORT,GL_FIXED 和GL_FLOAT,初始值爲GL_FLOAT。

 - stride——指明連續頂點間的位偏移,如果爲0,頂點被認爲是緊密壓入矩陣,初始值爲0。

 - pointer——指明頂點座標的緩衝區,如果爲null,則沒有設置緩衝區。

7、設置頂點的顏色爲綠色

這個就是設置頂點的顏色

8、設置點的大小

這個就是設置頂點的大小

9、繪製頂點

glDrawArrays(int mode, int first, int count)傳入三個參數,分別代表模式、繪製的起點、頂點數量

官方API解釋如下:

 - mode——指明渲染哪一種圖元。允許的符號常量有GL_POINTS,GL_LINE_STRIP,GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN 和GL_TRIANGLES。

 - first——指明在允許訪問的矩陣中的起始索引。

 - count——指明要渲染的索引的數量。

OpenGL ES提供了兩類方法來繪製一個空間幾何圖形:

 - public abstract void glDrawArrays(int mode, int first, int count) 使用VetexBuffer 來繪製,頂點的順序由vertexBuffer中的順序指定。

 - public abstract void glDrawElements(int mode, int count, int type, Buffer indices) ,可以重新定義頂點的順序,頂點的順序由indices Buffer 指定。

10、禁止頂點設置

繪製完成後,就關閉對應的功能。

三、效果

這裏寫圖片描述

附上Demo鏈接:打開鏈接
密碼:yvd5

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章