android openGL 魔方、贴图、混色

//设置光线,,1.0f为全光线,a=50%     
gl.glColor4f(1.0f,1.0f,1.0f,0.5f);       
// 基于源象素alpha通道值的半透明混合函数     
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE); 

只需增加上述方法即可开启,现在我们通过点触事件来控制其开启:

@Override     
public boolean onTouchEvent(MotionEvent event) {     
    // TODO Auto-generated method stub     
    if (event.getAction() == MotionEvent.ACTION_DOWN){     
        key = !key;     
    }     
    return super.onTouchEvent(event);     
}   

        完整代码如下:


package org.ourunix.android.opengltest;     
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.app.Activity;     
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.KeyEvent;     
import android.view.MotionEvent;     
     
public class OpenGLTestActivity extends Activity {     
    private boolean key = false;     
    /** Called when the activity is first created. */     
    @Override     
    public void onCreate(Bundle savedInstanceState) {     
        super.onCreate(savedInstanceState);     
        GLSurfaceView glView = new GLSurfaceView(this);     
        glView.setRenderer(new GLRender());     
        setContentView(glView);     
    }     
         
    public class GLRender implements Renderer{      
             
        private int texture = -1;     
        private int one = 0x10000;       
        private int[] quarter = {-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,};     
             
        private int[] texCoords = {one,0,0,0,0,one,one,one,      
                                0,0,0,one,one,one,one,0,     
                                one,one,one,0,0,0,0,one,     
                                0,one,one,one,one,0,0,0,     
                                0,0,0,one,one,one,one,0,     
                                one,0,0,0,0,one,one,one,};     
        //准备正方体顶点       
        private IntBuffer quarterBuffer = BufferUtil.iBuffer(quarter);       
        //纹理映射数据     
        private IntBuffer texCoordsBuffer = BufferUtil.iBuffer(texCoords);      
        ByteBuffer indicesBuffer = ByteBuffer.wrap(new byte[]{     
                0,1,3,2,     
                4,5,7,6,     
                8,9,11,10,     
                12,13,15,14,     
                16,17,19,18,     
                20,21,23,22,     
        });     
             
        private float rotateX; //用于正方体x轴的旋转;     
        private float rotateY; //用于正方体y轴的旋转;     
        private float rotateZ; //用于正方体z轴的旋转;     
             
        //定义环境光     
        private FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f, 0.5f, 0.5f, 1.0f });     
        //定义漫射光     
        private FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f, 1.0f, 1.0f, 1.0f });     
        //定义光源的位置     
        private FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f, 0.0f, 2.0f, 1.0f });     
        //咳,咳现在开始画图了       
        @Override       
        public void onDrawFrame(GL10 gl) {       
            // TODO Auto-generated method stub       
            //清楚屏幕和深度缓存       
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);     
            //重置当前的观察模型矩阵     
            gl.glLoadIdentity();     
            //开启光源     
            gl.glEnable(GL10.GL_LIGHTING);     
            //现将屏幕向里移动,用来画正方体       
            gl.glTranslatef(0.0f, 0.0f, -6.0f);      
            //设置3个方向的旋转     
            gl.glRotatef(rotateX, 1.0f, 0.0f, 0.0f);     
            gl.glRotatef(rotateY, 0.0f, 1.0f, 0.0f);     
            gl.glRotatef(rotateZ, 0.0f, 0.0f, 1.0f);     
            //通知opnegl将文理名字texture绑定到指定的纹理目标上GL10.GL_TEXTURE_2D     
            gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);     
                
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);      
            //纹理的使用与开启颜色渲染一样,需要开启纹理功能     
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);     
                 
            //设置正方体 各顶点     
            gl.glVertexPointer(3, GL10.GL_FIXED, 0, quarterBuffer);     
            gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoordsBuffer);     
                 
            //绘制     
            gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  GL10.GL_UNSIGNED_BYTE, indicesBuffer);     
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);     
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);     
                 
            rotateX += 0.5f;     
            rotateY += 0.6f;      
            rotateZ += 0.3f;      
                 
            //混合开关     
            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);    // 打开深度测试     
            }     
        }       
       
        //当窗口改变时,调用,至少在创建窗口时调用一次,这边设置下场景大小       
        @Override       
        public void onSurfaceChanged(GL10 gl, int width, int height) {       
            // TODO Auto-generated method stub       
            //设置OpenGL场景大小       
            float ratio = (float) width / height;       
            gl.glViewport(0, 0, 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) {       
            // TODO Auto-generated method stub       
            //设置清除屏幕时所用的颜色,参数依次为红、绿、蓝、Alpha值       
            gl.glClearColor(0, 0, 0, 0);     
            gl.glEnable(GL10.GL_CULL_FACE);     
            //启用阴影平滑       
            gl.glShadeModel(GL10.GL_SMOOTH);      
            gl.glEnable(GL10.GL_DEPTH_TEST);//启用深度测试       
                 
            //以下是关于深度缓存的设置,非常重要       
            gl.glClearDepthf(1.0f);//设置深度缓存       
            gl.glDepthFunc(GL10.GL_LEQUAL);//所做深度测试的类型       
                 
            //告诉系统对透视进行修正       
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);       
            //允许2D贴图     
            gl.glEnable(GL10.GL_TEXTURE_2D);     
                 
            IntBuffer intBuffer = IntBuffer.allocate(1);     
            //创建纹理     
            gl.glGenTextures(1, intBuffer);     
            texture = intBuffer.get();     
            //设置需要使用的纹理     
            gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);     
                 
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test);     
            //生成纹理     
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 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);     
                 
            //设置光线,,1.0f为全光线,a=50%     
            gl.glColor4f(1.0f,1.0f,1.0f,0.5f);       
            // 基于源象素alpha通道值的半透明混合函数     
            gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);       
                 
            //设置环境光     
            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);     
            //设置漫射光     
            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);     
            //设置光源的位置     
            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);     
            //开启ID号为GL_LIGHT1的光源     
            gl.glEnable(GL10.GL_LIGHT1);     
        }       
               
    }       
           
    public static class BufferUtil {       
        public static IntBuffer intBuffer;     
        public static FloatBuffer floatBuffer;     
       
        public static IntBuffer iBuffer(int[] a) {       
            // 先初始化buffer,数组的长度*4,因为一个float占4个字节       
            ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);       
            // 数组排列用nativeOrder       
            mbb.order(ByteOrder.nativeOrder());       
            intBuffer = mbb.asIntBuffer();       
            intBuffer.put(a);       
            intBuffer.position(0);       
            return intBuffer;       
        }       
             
        public static FloatBuffer fBuffer(float[] a) {       
            // 先初始化buffer,数组的长度*4,因为一个float占4个字节       
            ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);       
            // 数组排列用nativeOrder       
            mbb.order(ByteOrder.nativeOrder());       
            floatBuffer = mbb.asFloatBuffer();       
            floatBuffer.put(a);       
            floatBuffer.position(0);       
            return floatBuffer;       
        }     
    }     
         
    @Override     
    public boolean onTouchEvent(MotionEvent event) {     
        // TODO Auto-generated method stub     
        if (event.getAction() == MotionEvent.ACTION_DOWN){     
            key = !key;     
        }     
        return super.onTouchEvent(event);     
    }     
}   





你可能感兴趣的:(android开发)