Android:OpenGL與3D開發

一,OpenGL和OpenGL ES

簡介

OpenGL體系簡單,具有跨平臺的特性,不像Direct 3D只能在Windows系統上運行,因此OpenGL具有很廣泛的適應性——不僅只用於大型圖形工作站,也適用於PC。

OpenGL是高效,簡潔的開放圖形庫接口,定義了一個跨編程語言,跨平臺的編程接口規範,主要用於三維圖形編程。

在手機端上運行OpenGL有些不太合適,所以Android系統內置的是OpenGL ES。

OpenGL ES是免費的,跨平臺的,功能完善的2D/3D圖形庫接口API,它針對多種嵌入式程序專門設計,它是一個精心提取出來的OpenGL的子集。

OpenGL ES刪除了Open GL中glBegin/glEnd,四邊形,多邊形等非絕對必要的特性。

Android專門爲OpenGL支持增加了android.opengl包,在該包下提供了GLSurfaceView,GLU,GL Utils等工具類,通過這些工具類在Android應用中使用OpenGL ES更加方。

GLSurfaceView

在Android平臺上實現OpenGL的view用GLSurfaceView和GLSurfaceView.Renderer。

GLSurfaceView是用來連接OpenGL ES和android的view。

GLSurfaceView位於android.opengl包類,繼承自SurfaceView。

GLSurfaceView.Renderer

渲染器,是一個接口,位於GLSurfaceView類中。

MyRenderer

onSurfaceCreated——在Surface創建的時候調用

onSurfaceChanged——在Surface改變的時候調用

onDrawFrame——在Surface上繪製的時候調用

基礎框架

public class MainActivity extends AppCompatActivity {
    GLSurfaceView glSurfaceView;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        glSurfaceView = new GLSurfaceView(this);
        SecondActivity secondActivity = new SecondActivity();   //渲染器
        glSurfaceView.setRenderer(secondActivity);  //渲染器關聯起來

        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);//RENDERMODE_CONTINUOUSLY:持續渲染,機器會爆

        setContentView(glSurfaceView);
    }
}
================
public class SecondActivity implements GLSurfaceView.Renderer {
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0,255,0,0); //背景色
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {

    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    }
}

二,繪製點

1,定義頂點數組

2,獲取浮點形緩衝數據

3,設置清屏顏色,onSurfaceCreated裏調用glClearColor設置清屏顏色。

4,設置允許設置頂點,glEnableClientState(int array)調用客戶端的功能。

public class MainActivity extends FragmentActivity {
    GLSurfaceView glSurfaceView;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        glSurfaceView = new GLSurfaceView(this);
        SecondActivity secondActivity = new SecondActivity();   //渲染器
        glSurfaceView.setRenderer(secondActivity);  //渲染器關聯起來
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);//RENDERMODE_CONTINUOUSLY:持續渲染,機器會爆
        setContentView(glSurfaceView);
    }

}

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class SecondActivity implements GLSurfaceView.Renderer {
    private float[] mArray = new float[]{0f,0.5f,0f};
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0,255,0,0); //背景色
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0,0,width,height);//起始座標
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清屏
            //GL_COLOR_BUFFER_BIT:表明顏色緩衝區
            //GL_DEPTH_BUFFER_BIT:表明深度緩衝區
            //GL_STENCIL_BUFFER_BIT:表明模型緩衝區
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
            //GL_VERTEX_ARRAY:如果啓用,頂點矩陣可以用來寫入
            //GL_COLOR_ARRAY:如果啓用,顏色矩陣可以用來寫入
            //GL_NORMAL_ARRAY:如果啓用,法線矩陣可以用來寫入(用於光照處理)
            //GL_TEXTURE_COORD_ARRAY:如果啓用,紋理座標矩陣可以用來寫入
        gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));//指定數組頂點用
            //size:設置每個頂點的座標維數
            //type:GL_BYTE,GL_SHORT,GL_FIXED,GL_FLOAT,初始值爲GL_FLOAT
            //stride:指明連續頂點的位偏移,如果爲0,頂點被認爲是緊密壓入矩陣,初始值爲0
            //pointer:指明頂點座標的緩衝區,如果爲null,則沒有設置緩衝區
        gl.glColor4f(0,0,1,0);//畫圖顏色
        gl.glPointSize(80f);//大小
        gl.glDrawArrays(GL10.GL_POINTS,0,1);//畫點
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
    }
}
public class ThirdActivity {
    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;
    }
}

三,圖形繪製(三角形,矩形,正方形)

public class SecondActivity implements GLSurfaceView.Renderer {
    private float[] mArray = new float[]{
           /* -0.6f,0.6f,
            0f,-0.2f,
            0f,0f,*/
            0.2f,0.6f,
            0f,0.6f,
            0f,0f};
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0,0,0,0); //背景色
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0,0,width,height);//起始座標
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
            //GL_COLOR_BUFFER_BIT:表明顏色緩衝區
            //GL_DEPTH_BUFFER_BIT:表明深度緩衝區
            //GL_STENCIL_BUFFER_BIT:表明模型緩衝區
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
            //GL_VERTEX_ARRAY:頂點矩陣可以
        gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));//指定數組頂點用
        gl.glColor4f(255,255,255,0);//畫圖顏色
        gl.glDrawArrays(GL10.GL_TRIANGLES,0,5);//畫點
            //GL_POINTS:繪製獨立的點
            //GL_LINE_STRIP:繪製連續的線段,不封閉
            //GL_LINE_LOOP:繪製連續的線段,封閉
            //GL_LINES:頂點兩兩連接,爲多條線段構成
            //GL_TRIANGLES:每隔三個頂點構成一個三角形
            //GL_TRIANGLE_STRIP:每相鄰三個頂點組成一個三角形
            //GL_TRIANGLE_FAN:以一個點爲三角形公共頂點,組成一系列相鄰的三角形
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
    }
}

四,圖形變換(移動、旋轉、縮放、着色)

視角變換:人動,物體不動。     模型變換:物體動,人不動。

投影變換:人遠近調整。     視窗變換:把像素按照比例轉化後顯示到屏幕上。

視角變換和模型變換(平移,旋轉,縮放)

public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0,0,width,height);//起始座標
    //gl.glTranslatef(0.6f,0.3f,0f);  //平移
    //gl.glRotatef(45,0f,1f,0f);//旋轉
    //gl.glScalef(0.5f,0.5f,0.5f);//縮放
}

着色

int[] colors = new int[]{
            65535,0,0,0,    //紅
            0,65535,0,0,    //綠
            0,0,65535,0,    //藍
  };
public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
        gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));//指定數        組頂點用,轉二進制
        gl.glColorPointer(4,GL10.GL_FIXED,0,ThirdActivity.getIntBuffer(colors));//多色
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
 }
public static IntBuffer getIntBuffer(int [] vertexs){
        IntBuffer buffer;
        ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length*4);
        qbb.order(ByteOrder.nativeOrder());
        buffer = qbb.asIntBuffer();
        buffer.put(vertexs);
        buffer.position(0);
        return buffer;
    }

五,3D圖形繪製(三棱錐,立方體)

public class SecondActivity implements GLSurfaceView.Renderer {
    private float[] mArray = new float[]{
            0.0f,0.5f,0.0f,
            -0.5f,-0.5f,-0.2f,
            0.5f,0.5f,-0.2f,
            0.0f,-0.6f,0.2f,
            };
    int[] colors = new int[]{
            65535,0,0,0,    //紅
            0,65535,0,0,    //綠
            0,0,65535,0,    //藍
            0,65535,65535,0,    //藍
    };
    byte [] taperFacets= new byte[]{
            0,1,2,
            0,1,3,
            1,2,3,
            0,2,3,
    };
    public float b=45;
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0,0,0,0); //背景色
        gl.glShadeModel(GL10.GL_SMOOTH);    //打開平滑着色模式
        //gl.glTranslatef(0.6f,0f,0f);  //平移
        gl.glEnable(GL10.GL_DEPTH_TEST);    //啓用Z軸,啓動3D
        gl.glDepthFunc(GL10.GL_LEQUAL); //被遮擋的顏色要被顯示出來
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0,0,width,height);//起始座標
        gl.glMatrixMode(GL10.GL_PROJECTION); //正交投影
        gl.glLoadIdentity();//初始化單位矩陣
        //設置寬高比
        float a = (float)width/height;
        gl.glFrustumf(-a,a,-1,1,1f,1000f);   //設置透視投影的大小
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);//清除深度緩衝區

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//啓用顏色矩陣

        gl.glMatrixMode(GL10.GL_MODELVIEW); //物體變化前提
        gl.glLoadIdentity();

        gl.glTranslatef(0f,0f,-2.0f);   //平移,遠離我們
        gl.glRotatef(b,-0.1f,-0.1f,0.0f);

        gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));     //設置
        gl.glColorPointer(4,GL10.GL_FIXED,0,ThirdActivity.getIntBuffer(colors));

        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP,ThirdActivity.getByteBuffer(taperFacets).remaining(),
                GL10.GL_UNSIGNED_BYTE,ThirdActivity.getByteBuffer(taperFacets));        //畫圖模式、數組名、

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
        b+=1;
    }
}
public class SecondActivity implements GLSurfaceView.Renderer {
    private float[] mArray = new float[]{
            0.5f,0.5f,0.5f,
            0.5f,-0.5f,0.5f,
            -0.5f,-0.5f,0.5f,
            -0.5f,0.5f,0.5f,

            0.5f,0.5f,-0.5f,
            0.5f,-0.5f,-0.5f,
            -0.5f,-0.5f,-0.5f,
            -0.5f,0.5f,-0.5f,
            };
    int[] colors = new int[]{
            65535,0,0,0,    //紅
            0,0,65535,0,    //紅
            0,65535,0,0,    //紅
            65535,65535,0,0,    //紅
            0,65535,65535,0,    //紅
            65535,0,65535,0,    //紅
            0,0,0,0,    //紅
            65535,65535,65535,0,    //紅

    };
    byte [] taperFacets= new byte[]{
             0,1,2,
             0,2,3,
             2,3,7,
             2,6,7,
             0,3,7,
             0,4,7,
             4,5,6,
             4,6,7,
             0,1,4,
             1,4,5,
             1,2,6,
             1,5,6
    };
    public float b=45;
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(0,0,0,0); //背景色
        //gl.glShadeModel(GL10.GL_SMOOTH);    //打開平滑着色模式
        //gl.glTranslatef(0.6f,0f,0f);  //平移
        gl.glEnable(GL10.GL_DEPTH_TEST);    //啓用Z軸,啓動3D
        gl.glDepthFunc(GL10.GL_LEQUAL); //被遮擋的顏色要被顯示出來
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0,0,width,height);//起始座標
        gl.glMatrixMode(GL10.GL_PROJECTION); //正交投影
        gl.glLoadIdentity();//初始化單位矩陣
        //設置寬高比
        float a = (float)width/height;
        gl.glFrustumf(-a,a,-1,1,1f,1000f);   //設置透視投影的大小
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);//清除深度緩衝區

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//啓用顏色矩陣

        gl.glMatrixMode(GL10.GL_MODELVIEW); //物體變化前提
        gl.glLoadIdentity();

        gl.glTranslatef(0f,0f,-2.0f);   //平移,遠離我們
        gl.glRotatef(b,-0.1f,-0.1f,0.0f);

        gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));     //設置
        gl.glColorPointer(4,GL10.GL_FIXED,0,ThirdActivity.getIntBuffer(colors));

        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP,ThirdActivity.getByteBuffer(taperFacets).remaining(),
                GL10.GL_UNSIGNED_BYTE,ThirdActivity.getByteBuffer(taperFacets));        //畫圖模式、數組名、

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
        b+=1;
    }
}

六,3D圖形-貼圖

public class MainActivity extends Activity {
        // 定義旋轉角度
        private float anglex = 0f;
        private float angley = 0f;
        static final float ROTATE_FACTOR = 60;
        // 定義手勢檢測器實例
        GestureDetector detector;
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            // 創建一個GLSurfaceView,用於顯示OpenGL繪製的圖形
            GLSurfaceView glView = new GLSurfaceView(this);
            // 創建GLSurfaceView的內容繪製器
            MyRenderer myRender = new MyRenderer(this);
            // 爲GLSurfaceView設置繪製器
            glView.setRenderer(myRender);
            setContentView(glView);
            // 創建手勢檢測器
        }
        public class MyRenderer implements Renderer
        {
            // 立方體的頂點座標(一共是36個頂點,組成12個三角形)
            private float[] cubeVertices = { -0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
                    -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, -0.6f, -0.6f,
                    -0.6f, -0.6f, -0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
                    0.6f, 0.6f, 0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f,
                    0.6f, -0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f,
                    0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
                    -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f,
                    0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f,
                    -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f,
                    0.6f, 0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f,
                    -0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
                    -0.6f, 0.6f, -0.6f, };
            // 定義立方體所需要的6個面(一共是12個三角形所需的頂點)
            private byte[] cubeFacets = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
                    13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                    30, 31, 32, 33, 34, 35, };
            // 定義紋理貼圖的座標數據
            private float[] cubeTextures = { 1.0000f, 1.0000f, 1.0000f, 0.0000f,
                    0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 1.0000f,
                    1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f,
                    1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f,
                    1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f,
                    0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f,
                    1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f,
                    0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f,
                    0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f,
                    0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f,
                    0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f };
            private Context context;
            private FloatBuffer cubeVerticesBuffer;
            private ByteBuffer cubeFacetsBuffer;
            private FloatBuffer cubeTexturesBuffer;
            // 定義本程序所使用的紋理
            private int texture;
            public MyRenderer(Context main)
            {
                this.context = main;
                // 將立方體的頂點位置數據數組包裝成FloatBuffer;
                cubeVerticesBuffer = floatBufferUtil(cubeVertices);
                // 將立方體的6個面(12個三角形)的數組包裝成ByteBuffer
                cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);
                // 將立方體的紋理貼圖的座標數據包裝成FloatBuffer
                cubeTexturesBuffer = floatBufferUtil(cubeTextures);
            }
            @Override
            public void onSurfaceCreated(GL10 gl, EGLConfig config)
            {
                // 關閉抗抖動
                gl.glDisable(GL10.GL_DITHER);
                // 設置系統對透視進行修正
                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
                gl.glClearColor(0, 0, 0, 0);
                // 設置陰影平滑模式
                gl.glShadeModel(GL10.GL_SMOOTH);
                // 啓用深度測試
                gl.glEnable(GL10.GL_DEPTH_TEST);
                // 設置深度測試的類型
                gl.glDepthFunc(GL10.GL_LEQUAL);
                // 啓用2D紋理貼圖
                gl.glEnable(GL10.GL_TEXTURE_2D);
                // 裝載紋理
                loadTexture(gl);
            }
            @Override
            public void onSurfaceChanged(GL10 gl, int width, int height)
            {
                // 設置3D視窗的大小及位置
                gl.glViewport(0, 0, width, height);
                // 將當前矩陣模式設爲投影矩陣
                gl.glMatrixMode(GL10.GL_PROJECTION);
                // 初始化單位矩陣
                gl.glLoadIdentity();
                // 計算透視視窗的寬度、高度比
                float ratio = (float) width / height;
                // 調用此方法設置透視視窗的空間大小。
                gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
            }
            public void onDrawFrame(GL10 gl)
            {
                // 清除屏幕緩存和深度緩存
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
                // 啓用頂點座標數據
                gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
                // 啓用貼圖座標數組數據
                gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);   // ①
                // 設置當前矩陣模式爲模型視圖。
                gl.glMatrixMode(GL10.GL_MODELVIEW);
                gl.glLoadIdentity();
                // 把繪圖中心移入屏幕2個單位
                gl.glTranslatef(0f, 0.0f, -2.0f);
                // 旋轉圖形
                gl.glRotatef(angley, 0, 1, 0);
                gl.glRotatef(anglex, 1, 0, 0);
                // 設置頂點的位置數據
                gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer);
                // 設置貼圖的座標數據
                gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);  // ②
                // 執行紋理貼圖
                gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);  // ③
                // 按cubeFacetsBuffer指定的面繪製三角形
                gl.glDrawElements(GL10.GL_TRIANGLES, cubeFacetsBuffer.remaining(),
                        GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer);
                // 繪製結束
                gl.glFinish();
                // 禁用頂點、紋理座標數組
                gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
                gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
                // 遞增角度值以便每次以不同角度繪製
                angley++;
            }
            private void loadTexture(GL10 gl)
            {
                Bitmap bitmap = null;
                try
                {
                    // 加載位圖
                    bitmap = BitmapFactory.decodeResource(context.getResources(),
                            R.drawable.huaji);
                    int[] textures = new int[1];
                    // 指定生成N個紋理(第一個參數指定生成一個紋理)
                    // textures數組將負責存儲所有紋理的代號
                    gl.glGenTextures(1, textures, 0);
                    // 獲取textures紋理數組中的第一個紋理
                    texture = textures[0];
                    // 通知OpenGL將texture紋理綁定到GL10.GL_TEXTURE_2D目標中
                    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
                    // 設置紋理被縮小(距離視點很遠時被縮小)時的濾波方式
                    gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                            GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                    // 設置紋理被放大(距離視點很近時被方法)時的濾波方式
                    gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                            GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
                    // 設置在橫向、縱向上都是平鋪紋理
                    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                            GL10.GL_REPEAT);
                    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                            GL10.GL_REPEAT);
                    // 加載位圖生成紋理
                    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
                }
                finally
                {
                    // 生成紋理之後,回收位圖
                    if (bitmap != null)
                        bitmap.recycle();
                }
            }
        }

        // 定義一個工具方法,將float[]數組轉換爲OpenGL ES所需的FloatBuffer
        private FloatBuffer floatBufferUtil(float[] arr)
        {
            FloatBuffer mBuffer;
            // 初始化ByteBuffer,長度爲arr數組的長度*4,因爲一個int佔4個字節
            ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
            // 數組排列用nativeOrder
            qbb.order(ByteOrder.nativeOrder());
            mBuffer = qbb.asFloatBuffer();
            mBuffer.put(arr);
            mBuffer.position(0);
            return mBuffer;
        }
    }

 

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