android opengl es 混合效果

Activity類

 

package sim.feel;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;

public class my3d4 extends Activity {
    /** Called when the activity is first created. */

    private MyRenderer renderer = new MyRenderer();
    private GLSurfaceView glSurfaceView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BitGL.init(getResources());
        glSurfaceView = new GLSurfaceView(this);
       
        glSurfaceView.setRenderer(renderer);
        setContentView(glSurfaceView);
    }

    // 處理事件
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        renderer.onKeyDown(keyCode, event);
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        renderer.onKeyUp(keyCode, event);
        return super.onKeyUp(keyCode, event);
    }
}

class BitGL {
    public static Bitmap bitmap;

    public static void init(Resources resources) {
        bitmap = BitmapFactory.decodeResource(resources, R.drawable.img);
    }
}

 

 

Renderer類

 

package sim.feel;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

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

import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.view.KeyEvent;

public class MyRenderer implements Renderer {
    float step = 0.4f;
    boolean key;
    boolean light = true;

    float xrot, yrot; // x,y軸旋轉
    float xspeed, yspeed;// 旋轉的速度
    private int one = 0x10000;
    private int[] textures = new int[1];
    /**
     * @param context
     *            頂點及紋理
     */
    // verticesBuffer
    private IntBuffer verticesBuffer;
    // texcoordBuffer
    private IntBuffer texcoordBuffer;
    // 頂點數組vertices
    private int[] vertices;
    // 紋理數組texcoord
    private int[] texcoord;

    /**
     * @param context
     *            光線
     */
    // lightAmbientBuffer
    private FloatBuffer lightAmbientBuffer;
    // 環境光lightAmbient
    private float[] lightAmbient;
    // lightDiffuseBuffer
    private FloatBuffer lightDiffuseBuffer;
    // 漫射光lightDiffuse
    private float[] lightDiffuse;
    // lightPositionBuffer
    private FloatBuffer lightPositionBuffer;
    // 光源的位置
    private float[] lightPosition;

    // 構造方法
    public MyRenderer() {
        // 在構造方法中初始化
        initData();
        initBuffer();
    }

    // 初始化各類值
    public 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 };

        texcoord = 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 void initBuffer() {
        // verticesbyteBuffer
        ByteBuffer verticesbyteBuffer = ByteBuffer
                .allocateDirect(vertices.length * 4);
        verticesbyteBuffer.order(ByteOrder.nativeOrder());
        verticesBuffer = verticesbyteBuffer.asIntBuffer();
        verticesBuffer.put(vertices);
        verticesBuffer.position(0);

        // texcoordBuffer
        ByteBuffer texcoordbyteBuffer = ByteBuffer
                .allocateDirect(texcoord.length * 4 * 6);
        texcoordbyteBuffer.order(ByteOrder.nativeOrder());
        texcoordBuffer = texcoordbyteBuffer.asIntBuffer();
        for (int i = 0; i < 6; i++) {
            texcoordBuffer.put(texcoord);
        }
        texcoordBuffer.position(0);

        // lightAmbientBuffer
        ByteBuffer lightAmbientbyteBuffer = ByteBuffer
                .allocateDirect(lightAmbient.length * 4 * 6);
        lightAmbientbyteBuffer.order(ByteOrder.nativeOrder());
        lightAmbientBuffer = lightAmbientbyteBuffer.asFloatBuffer();
        lightAmbientBuffer.put(lightAmbient);
        lightAmbientBuffer.position(0);

        // lightAmbientBuffer
        ByteBuffer lightPositionbyteBuffer = ByteBuffer
                .allocateDirect(lightPosition.length * 4 * 6);
        lightPositionbyteBuffer.order(ByteOrder.nativeOrder());
        lightPositionBuffer = lightPositionbyteBuffer.asFloatBuffer();
        lightPositionBuffer.put(lightPosition);
        lightPositionBuffer.position(0);

        // lightAmbientBuffer
        ByteBuffer lightDiffusebyteBuffer = ByteBuffer
                .allocateDirect(lightDiffuse.length * 4 * 6);
        lightDiffusebyteBuffer.order(ByteOrder.nativeOrder());
        lightDiffuseBuffer = lightDiffusebyteBuffer.asFloatBuffer();
        lightDiffuseBuffer.put(lightDiffuse);
        lightDiffuseBuffer.position(0);
    }

    @Override
    public void onDrawFrame(GL10 gl) {

        // 清除深度緩存和顏色
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_COLOR_BUFFER_BIT);
        // 重置觀察模型
        gl.glLoadIdentity();

        // 如果不啓用GL_LIGHTING光就什麼都看不見
        gl.glEnable(GL10.GL_LIGHTING);
        // 啓用vertex及texcoord
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // 向左移動1.5f並向裏移動6.0f
        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, verticesBuffer);
        // 指定紋理映射(每次都寫錯,煩)
        gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texcoordBuffer);

        for (int i = 0; i < 6; i++) {
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4);
        }

        // 取消頂點及紋理映射
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

        xrot += xspeed;
        yrot += yspeed;
       
         //混合開關
        if (key)
        {
            gl.glEnable(GL10.GL_BLEND);        // 打開混合
            gl.glDisable(GL10.GL_DEPTH_TEST);    // 關閉深度測試
        }
        else
        {
            gl.glDisable(GL10.GL_BLEND);        // 關閉混合
            gl.glEnable(GL10.GL_DEPTH_TEST);    // 打開深度測試
        }


        if (!light) // 判斷是否開始光源
        {
            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, BitGL.bitmap, 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, lightAmbientBuffer);

        // 設置漫射光
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuseBuffer);

        // 設置光源的位置
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPositionBuffer);

        // 啓用一號光源
        gl.glEnable(GL10.GL_LIGHT1);

        // 啓用混合
        gl.glEnable(GL10.GL_BLEND);

    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_UP:
            key = true;
            xspeed = -step;
            break;
        case KeyEvent.KEYCODE_DPAD_DOWN:
            key = true;
            xspeed = step;
            break;
        case KeyEvent.KEYCODE_DPAD_LEFT:
            key = true;
            yspeed = -step;
            break;
        case KeyEvent.KEYCODE_DPAD_RIGHT:
            key = true;
            yspeed = step;
            break;
        case KeyEvent.KEYCODE_DPAD_CENTER:
            light = !light;
            break;
        }
        return false;
    }

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        key = false;
        return false;
    }

}

 

效果圖

 

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