[Android開發學習18]Android OpenGL ES 光照glDrawArrays

一、基礎知識:

1..光照介紹:

①環境光:
 來自四面八方,所有場景中的對象都處於環境光的照射中。

②漫射光:
 由特定的光源產生,並在場景中的對象表面產生反射。
 處於漫射光直接照射下的任何對象表面都變得很亮,而幾乎未被照射到的區域就顯示得要暗一些。

 

2.光照使用:
①設定光源參數:

 //環境光
 private float[] lightAmbient;
 private FloatBuffer AmbientBuffer;
 //漫射光
 private float[] lightDiffuse;
 private FloatBuffer diffuseBuffer;
 //光源位置
 private float[] lightPosition;
 private FloatBuffer positionBuffer;

 //燈光
 lightAmbient = new float[]{0.5f,0.5f,0.5f,1.0f};
 lightDiffuse = new float[]{1.0f,1.0f,1.0f,1.0f};
 lightPosition = new float[]{0.0f,0.0f,2.0f,1.0f};

 //環境光
 ByteBuffer ambientbb = ByteBuffer.allocateDirect(lightAmbient.length * 4 * 6);
 ambientbb.order(ByteOrder.nativeOrder());
 AmbientBuffer = ambientbb.asFloatBuffer();
 AmbientBuffer.put(lightAmbient);
 AmbientBuffer.position(0);
 
 //漫射光
 ByteBuffer diffusebb = ByteBuffer.allocateDirect(lightDiffuse.length * 4 * 6);
 diffusebb.order(ByteOrder.nativeOrder());
 diffuseBuffer = diffusebb.asFloatBuffer();
 diffuseBuffer.put(lightDiffuse);
 diffuseBuffer.position(0);
 
 //燈光位置
 ByteBuffer positionbb = ByteBuffer.allocateDirect(lightPosition.length * 4 * 6);
 positionbb.order(ByteOrder.nativeOrder());
 positionBuffer = positionbb.asFloatBuffer();
 positionBuffer.put(lightPosition);
 positionBuffer.position(0);

 

②設置光源:
 glLightfv (
  int light,  // 光源的ID
  int pname,   // 光源的類型
  FloatBuffer params // 光源的數組
 )
設定的屬性,主要由第二個參數決定:
GL_AMBIENT 環境光(光源泛光強度的RGBA值)
GL_DIFFUSE 漫射光(光源漫反射強度的RGBA值)
GL_SPECULAR 高光(光源鏡面反射強度的RGBA值)
GL_POSITION 位置(光源的位置)
GL_SPOT_DIRECTION 方向(聚光燈的方向)
GL_SPOT_CUTOFF 光的角度(聚光燈的截止角度)

 

 // 設置環境光
 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, AmbientBuffer);
 // 設置漫射光
 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseBuffer);
 // 設置燈光位置
 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionBuffer);

③啟用光源:
 //啟用一號光源
 gl.glEnable(GL10.GL_LIGHT1);

 

 

 

二、實現:

1. 界面編輯:
【res\layout\main.xml】

[html]
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
<TextView   
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content"  
    android:text="@string/hello" 
    /> 
 
<Button 
    android:id="@+id/button1" 
    android:layout_width="145dp" 
    android:layout_height="wrap_content" 
    android:text="演示開始" /> 
 
</LinearLayout> 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />

<Button
    android:id="@+id/button1"
    android:layout_width="145dp"
    android:layout_height="wrap_content"
    android:text="演示開始" />

</LinearLayout>

 

2.代碼編輯:
【\src\com\yarin\android\Examples\Activity01.java】

[java]
package com.yarin.android.Examples_12_05; 
 
import java.io.IOException; 
import java.io.InputStream; 
 
import javax.microedition.khronos.opengles.GL10; 
 
import android.app.Activity; 
import android.content.res.Resources; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLSurfaceView; 
import android.opengl.GLUtils; 
import android.opengl.GLSurfaceView.Renderer; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
 
public class Activity01 extends Activity 

    Renderer render = new GLRender(); 
    GLSurfaceView glView; 
    Button start;           // 演示開始  
 
     
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
        super.onCreate(savedInstanceState); 
        GLImage.load(this.getResources()); 
        glView = new GLSurfaceView(this); 
         
         
        glView.setRenderer(render); 
        setContentView(R.layout.main); 
        start=(Button)findViewById(R.id.button1);   // "演示開始"按鈕初始化  
        start.setOnClickListener(new View.OnClickListener() { 
             
            @Override 
            public void onClick(View v) { 
                // TODO Auto-generated method stub  
                setContentView(glView); 
            } 
        }); 
         
        //setContentView(glView);  
    } 

 
class GLImage 

    public static Bitmap iBitmap; 
    public static Bitmap jBitmap; 
    public static Bitmap kBitmap; 
    public static Bitmap lBitmap; 
    public static Bitmap mBitmap; 
    public static Bitmap nBitmap; 
    public static Bitmap close_Bitmap; 
     
     
    public static void load(Resources resources) 
    { 
        iBitmap = BitmapFactory.decodeResource(resources, R.drawable.img); 
        jBitmap = BitmapFactory.decodeResource(resources, R.drawable.jmg); 
        kBitmap = BitmapFactory.decodeResource(resources, R.drawable.kmg); 
        lBitmap = BitmapFactory.decodeResource(resources, R.drawable.lmg); 
        mBitmap = BitmapFactory.decodeResource(resources, R.drawable.mmg); 
        nBitmap = BitmapFactory.decodeResource(resources, R.drawable.nmg); 
        close_Bitmap = BitmapFactory.decodeResource(resources, R.drawable.close); 
    } 

package com.yarin.android.Examples_12_05;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class Activity01 extends Activity
{
 Renderer render = new GLRender();
 GLSurfaceView glView;
 Button start;   // 演示開始

 
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  GLImage.load(this.getResources());
  glView = new GLSurfaceView(this);
  
  
  glView.setRenderer(render);
  setContentView(R.layout.main);
  start=(Button)findViewById(R.id.button1); // "演示開始"按鈕初始化
  start.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    setContentView(glView);
   }
  });
  
  //setContentView(glView);
 }
}

class GLImage
{
 public static Bitmap iBitmap;
 public static Bitmap jBitmap;
 public static Bitmap kBitmap;
 public static Bitmap lBitmap;
 public static Bitmap mBitmap;
 public static Bitmap nBitmap;
 public static Bitmap close_Bitmap;
 
 
 public static void load(Resources resources)
 {
  iBitmap = BitmapFactory.decodeResource(resources, R.drawable.img);
  jBitmap = BitmapFactory.decodeResource(resources, R.drawable.jmg);
  kBitmap = BitmapFactory.decodeResource(resources, R.drawable.kmg);
  lBitmap = BitmapFactory.decodeResource(resources, R.drawable.lmg);
  mBitmap = BitmapFactory.decodeResource(resources, R.drawable.mmg);
  nBitmap = BitmapFactory.decodeResource(resources, R.drawable.nmg);
  close_Bitmap = BitmapFactory.decodeResource(resources, R.drawable.close);
 }
}

 

【\src\com\yarin\android\Examples\GLRender.java】

[java]
package com.yarin.android.Examples_12_05; 
 
import java.io.IOException; 
import java.io.InputStream; 
import java.nio.ByteBuffer; 
import java.nio.IntBuffer; 
import java.nio.ByteOrder;   
import java.nio.FloatBuffer; 
 
import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 
 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLUtils; 
import android.opengl.GLSurfaceView.Renderer; 
import android.content.Context; 
 
public class GLRender implements Renderer 

    /**
     * 渲染類
     * author:pis
     */ 
 
    private int one = 0x10000; 
 
    public boolean mFlag ; 
    public boolean bLight = true;//是否開啟燈光  
     
    private int[] vertices;//頂點數組  
    private int[] textCood;//紋理數組  
     
    float step = 0.3f; 
    float xrot,yrot; //旋轉  
    float xSpeed,ySpeed; //移動速度  
    private int[] textures = new int[1]; 
     
    private IntBuffer vertexBuffer; //頂點緩沖  
    private IntBuffer textCoodBuffer; //紋理緩沖  
    /**
     * 設置燈光
     * @param context
     */ 
    //環境光  
    private float[] lightAmbient; 
    private FloatBuffer AmbientBuffer; 
    //漫射光  
    private float[] lightDiffuse; 
    private FloatBuffer diffuseBuffer; 
    //光源位置  
    private float[] lightPosition; 
    private FloatBuffer positionBuffer; 
     
    /**
     * 初始化緩沖數據
     */ 
    private void initBuffer(){ 
        //頂點  
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); 
        vbb.order(ByteOrder.nativeOrder()); 
        vertexBuffer = vbb.asIntBuffer(); 
        vertexBuffer.put(vertices); 
        vertexBuffer.position(0); 
         
        //紋理  
        ByteBuffer tbb = ByteBuffer.allocateDirect(textCood.length * 4 * 6); 
        tbb.order(ByteOrder.nativeOrder()); 
        textCoodBuffer = tbb.asIntBuffer(); 
        for (int i = 0; i < 6; i++) {             
            textCoodBuffer.put(textCood); 
        } 
        textCoodBuffer.position(0); 
         
        //環境光  
        ByteBuffer ambientbb = ByteBuffer.allocateDirect(lightAmbient.length * 4 * 6); 
        ambientbb.order(ByteOrder.nativeOrder()); 
        AmbientBuffer = ambientbb.asFloatBuffer(); 
        AmbientBuffer.put(lightAmbient); 
        AmbientBuffer.position(0); 
         
        //漫射光  
        ByteBuffer diffusebb = ByteBuffer.allocateDirect(lightDiffuse.length * 4 * 6); 
        diffusebb.order(ByteOrder.nativeOrder()); 
        diffuseBuffer = diffusebb.asFloatBuffer(); 
        diffuseBuffer.put(lightDiffuse); 
        diffuseBuffer.position(0); 
         
        //燈光位置  
        ByteBuffer positionbb = ByteBuffer.allocateDirect(lightPosition.length * 4 * 6); 
        positionbb.order(ByteOrder.nativeOrder()); 
        positionBuffer = positionbb.asFloatBuffer(); 
        positionBuffer.put(lightPosition); 
        positionBuffer.position(0); 
         
    } 
    /**
     * 初始化頂點、紋理、燈光數據
     */ 
    private void initData(){ 
        //頂點數組  
        vertices = new int[] { -one, -one, one, one, -one, one, -one, one, one, 
                one, one, one, one, -one, one, one, -one, -one, one, one, one, 
                one, one, -one, one, -one, -one, -one, -one, -one, one, one, 
                -one, -one, one, -one, -one, -one, -one, -one, -one, one, -one, 
                one, -one, -one, one, one, -one, one, -one, one, one, -one, 
                -one, one, one, one, one, one, -one, -one, -one, -one, -one, 
                one, one, -one, -one, one, -one, one }; 
 
        //紋理數組,貼圖時註意android中坐標與OpengGL 中定義的不同,android,y軸是向下的  
        textCood = new int[] { 0, 0, one, 0, 0, one, one, one }; 
        //燈光  
        lightAmbient = new float[]{0.5f,0.5f,0.5f,1.0f}; 
        lightDiffuse = new float[]{1.0f,1.0f,1.0f,1.0f}; 
        lightPosition = new float[]{0.0f,0.0f,2.0f,1.0f}; 
 
         
    } 
    public GLRender() { 
        mFlag=true; 
        initData(); 
        initBuffer(); 
    } 
 
     
    @Override 
    public void onDrawFrame(GL10 gl) { 
        //清除顏色和深度緩存  
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
        gl.glLoadIdentity(); 
         
        //啟用燈光  
        gl.glEnable(GL10.GL_LIGHTING); 
         
        //啟用頂點和紋理緩存  
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
        //移動和旋轉設置  
        gl.glTranslatef(0.0f, 0.0f, -6.0f); 
        gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); 
        gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); 
         
        //設置頂點和紋理,經常忘記設置,唉!  
        gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer); 
        gl.glTexCoordPointer(2,GL10.GL_FIXED,0,textCoodBuffer); 
         
        //繪制六個面,貼圖  
        for (int i = 0; i < 6; i++) { 
            switch(i) 
            { 
            case 0: 
                // 8.生成紋理  
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0); 
                break; 
            case 1: 
                // 生成紋理  
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.jBitmap, 0); 
                break; 
            case 2: 
                // 生成紋理  
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.kBitmap, 0); 
                break; 
            case 3: 
                // 生成紋理  
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.lBitmap, 0); 
                break; 
            case 4: 
                // 生成紋理  
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0); 
                break; 
            case 5: 
                // 生成紋理  
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.nBitmap, 0); 
                break;                               
            }            
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4); 
        } 
        //取消緩存,需我們自己手動  
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
        gl.glLoadIdentity(); 
         
        if (mFlag) { 
            xrot += 0.5f; 
            yrot += 0.5f; 
        } 
        if (!bLight) { 
            gl.glDisable(GL10.GL_LIGHT1); 
        } else { 
            gl.glEnable(GL10.GL_LIGHT1); 
        } 
    } 
 
    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
        //場景大小  
        gl.glViewport(0, 0, width, height); 
        float ratio = (float) width / height; 
        //投影矩陣  
        gl.glMatrixMode(GL10.GL_PROJECTION); 
        //重置下  
        gl.glLoadIdentity(); 
        //視圖大小設置  
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); 
        //觀察模型  
        gl.glMatrixMode(GL10.GL_MODELVIEW); 
        gl.glLoadIdentity(); 
    } 
 
    @Override 
    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); 
        //清除深度緩存  
        gl.glClearDepthf(one); 
        //啟用深度緩存  
        gl.glEnable(GL10.GL_DEPTH_TEST); 
        //深度緩存模式  
        gl.glDepthFunc(GL10.GL_LEQUAL); 
         
        /**
         * 設置紋理
         */ 
        //啟用紋理  
        gl.glEnable(GL10.GL_TEXTURE_2D); 
        //創建紋理  
        gl.glGenTextures(1, textures, 0); 
        //綁定紋理  
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 
        //生成紋理  
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.kBitmap, 0); 
        //線性濾波處理  
        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, 
                GL10.GL_LINEAR); 
        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, 
                GL10.GL_LINEAR); 
        /**
         * 設置燈光
         */ 
         
        //設置環境光  
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, AmbientBuffer); 
        //設置漫射光  
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseBuffer); 
        //設置燈光位置  
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionBuffer); 
        //啟用1號燈光  
        gl.glEnable(GL10.GL_LIGHT1);     
         
    } 

package com.yarin.android.Examples_12_05;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ByteOrder; 
import java.nio.FloatBuffer;

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

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.content.Context;

public class GLRender implements Renderer
{
 /**
  * 渲染類
  * author:pis
  */

 private int one = 0x10000;

 public boolean mFlag ;
 public boolean bLight = true;//是否開啟燈光
 
 private int[] vertices;//頂點數組
 private int[] textCood;//紋理數組
 
 float step = 0.3f;
 float xrot,yrot; //旋轉
 float xSpeed,ySpeed; //移動速度
 private int[] textures = new int[1];
 
 private IntBuffer vertexBuffer; //頂點緩沖
 private IntBuffer textCoodBuffer; //紋理緩沖
 /**
  * 設置燈光
  * @param context
  */
 //環境光
 private float[] lightAmbient;
 private FloatBuffer AmbientBuffer;
 //漫射光
 private float[] lightDiffuse;
 private FloatBuffer diffuseBuffer;
 //光源位置
 private float[] lightPosition;
 private FloatBuffer positionBuffer;
 
 /**
  * 初始化緩沖數據
  */
 private void initBuffer(){
  //頂點
  ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
  vbb.order(ByteOrder.nativeOrder());
  vertexBuffer = vbb.asIntBuffer();
  vertexBuffer.put(vertices);
  vertexBuffer.position(0);
  
  //紋理
  ByteBuffer tbb = ByteBuffer.allocateDirect(textCood.length * 4 * 6);
  tbb.order(ByteOrder.nativeOrder());
  textCoodBuffer = tbb.asIntBuffer();
  for (int i = 0; i < 6; i++) {   
   textCoodBuffer.put(textCood);
  }
  textCoodBuffer.position(0);
  
  //環境光
  ByteBuffer ambientbb = ByteBuffer.allocateDirect(lightAmbient.length * 4 * 6);
  ambientbb.order(ByteOrder.nativeOrder());
  AmbientBuffer = ambientbb.asFloatBuffer();
  AmbientBuffer.put(lightAmbient);
  AmbientBuffer.position(0);
  
  //漫射光
  ByteBuffer diffusebb = ByteBuffer.allocateDirect(lightDiffuse.length * 4 * 6);
  diffusebb.order(ByteOrder.nativeOrder());
  diffuseBuffer = diffusebb.asFloatBuffer();
  diffuseBuffer.put(lightDiffuse);
  diffuseBuffer.position(0);
  
  //燈光位置
  ByteBuffer positionbb = ByteBuffer.allocateDirect(lightPosition.length * 4 * 6);
  positionbb.order(ByteOrder.nativeOrder());
  positionBuffer = positionbb.asFloatBuffer();
  positionBuffer.put(lightPosition);
  positionBuffer.position(0);
  
 }
 /**
  * 初始化頂點、紋理、燈光數據
  */
 private void initData(){
  //頂點數組
  vertices = new int[] { -one, -one, one, one, -one, one, -one, one, one,
                one, one, one, one, -one, one, one, -one, -one, one, one, one,
                one, one, -one, one, -one, -one, -one, -one, -one, one, one,
                -one, -one, one, -one, -one, -one, -one, -one, -one, one, -one,
                one, -one, -one, one, one, -one, one, -one, one, one, -one,
                -one, one, one, one, one, one, -one, -one, -one, -one, -one,
                one, one, -one, -one, one, -one, one };

  //紋理數組,貼圖時註意android中坐標與OpengGL 中定義的不同,android,y軸是向下的
  textCood = new int[] { 0, 0, one, 0, 0, one, one, one };
  //燈光
  lightAmbient = new float[]{0.5f,0.5f,0.5f,1.0f};
  lightDiffuse = new float[]{1.0f,1.0f,1.0f,1.0f};
  lightPosition = new float[]{0.0f,0.0f,2.0f,1.0f};

  
 }
 public GLRender() {
  mFlag=true;
  initData();
  initBuffer();
 }

 
 @Override
 public void onDrawFrame(GL10 gl) {
  //清除顏色和深度緩存
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  gl.glLoadIdentity();
  
  //啟用燈光
  gl.glEnable(GL10.GL_LIGHTING);
  
  //啟用頂點和紋理緩存
  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  //移動和旋轉設置
  gl.glTranslatef(0.0f, 0.0f, -6.0f);
  gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
  gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
  
  //設置頂點和紋理,經常忘記設置,唉!
  gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer);
  gl.glTexCoordPointer(2,GL10.GL_FIXED,0,textCoodBuffer);
  
  //繪制六個面,貼圖
  for (int i = 0; i < 6; i++) {
        switch(i)
         {
         case 0:
             // 8.生成紋理
             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0);
             break;
         case 1:
             // 生成紋理
             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.jBitmap, 0);
             break;
         case 2:
             // 生成紋理
             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.kBitmap, 0);
             break;
         case 3:
             // 生成紋理
             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.lBitmap, 0);
             break;
         case 4:
             // 生成紋理
             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);
             break;
         case 5:
             // 生成紋理
             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.nBitmap, 0);
             break;                       
         }   
   gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4);
  }
  //取消緩存,需我們自己手動
  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  gl.glLoadIdentity();
  
  if (mFlag) {
   xrot += 0.5f;
   yrot += 0.5f;
  }
  if (!bLight) {
   gl.glDisable(GL10.GL_LIGHT1);
  } else {
   gl.glEnable(GL10.GL_LIGHT1);
  }
 }

 @Override
 public void onSurfaceChanged(GL10 gl, int width, int height) {
  //場景大小
  gl.glViewport(0, 0, width, height);
  float ratio = (float) width / height;
  //投影矩陣
  gl.glMatrixMode(GL10.GL_PROJECTION);
  //重置下
  gl.glLoadIdentity();
  //視圖大小設置
  gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
  //觀察模型
  gl.glMatrixMode(GL10.GL_MODELVIEW);
  gl.glLoadIdentity();
 }

 @Override
 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);
  //清除深度緩存
  gl.glClearDepthf(one);
  //啟用深度緩存
  gl.glEnable(GL10.GL_DEPTH_TEST);
  //深度緩存模式
  gl.glDepthFunc(GL10.GL_LEQUAL);
  
  /**
   * 設置紋理
   */
  //啟用紋理
  gl.glEnable(GL10.GL_TEXTURE_2D);
  //創建紋理
  gl.glGenTextures(1, textures, 0);
  //綁定紋理
  gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
  //生成紋理
  GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.kBitmap, 0);
  //線性濾波處理
  gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
    GL10.GL_LINEAR);
  gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
    GL10.GL_LINEAR);
  /**
   * 設置燈光
   */
  
  //設置環境光
  gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, AmbientBuffer);
  //設置漫射光
  gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseBuffer);
  //設置燈光位置
  gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionBuffer);
  //啟用1號燈光
  gl.glEnable(GL10.GL_LIGHT1); 
  
 }
}

 

 

三、效果:

 

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *