android opengl es 3d 贴图 旋转立方体demo

效果展示

源码和apk的下载

资源下载

核心代码

package com.rex;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;

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

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

/**
 * Created by  Rex on 2017/3/20.
 * 带贴纸的立方体0
 */
public class MyGLRenderer2 implements GLSurfaceView.Renderer {

    MainActivity temp2Activity;

    public MyGLRenderer2(MainActivity temp2Activity) {
        this.temp2Activity = temp2Activity;

        createBuffer();
    }


    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        boolean SEE_THRU = true;
        gl.glDisable(GL10.GL_DITHER);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

        //在位置(1,1,1)处定义光源
        float lightAmbient[] = new float[]{0.3f, 0.3f, 0.3f, 1};
        float lightDiffuse[] = new float[]{1, 1, 1, 1};
        float lightPos[] = new float[]{1, 1, 1, 1};

        gl.glEnable(GL10.GL_LIGHTING);//禁用颜色抖动 消除可能性的性能高消耗
        gl.glEnable(GL10.GL_LIGHT0);//设置清除颜色缓冲区时用的RGBA颜色值

        //设置环境光
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);

        //设置漫射光
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);

        //设置光源位置
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);

        //定义立方体材质
        float matAmbient[] = new float[]{1, 1, 1, 1};
        float matDiffuse[] = new float[]{1, 1, 1, 1};
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0);
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0);

        // 设置需要的OpenGL项目
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glClearDepthf(1f);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        //设置透明效果
        if (SEE_THRU) {
            gl.glDisable(GL10.GL_DEPTH_TEST);
            gl.glEnable(GL10.GL_BLEND);
            gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
        }

        //加载纹理图片
        gl.glEnable(GL10.GL_TEXTURE_2D);
        loadTextuer(gl);
    }

    private void loadTextuer(GL10 gl) {
        Bitmap bitmap = null;

        try {
            bitmap = BitmapFactory.decodeResource(temp2Activity.getResources(), R.mipmap.jixie999);

            int[] textures = new int[1];
            gl.glGenTextures(1,textures,0);//生成一组纹理并把纹理的ID存入数组参数中
            texture = textures[0];

            gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);//将指定id的纹理绑定到指定的目标中去

            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);

            //将bitmap设置到纹理目录中
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bitmap,0);

        } catch (Exception e) {

        }
        finally {
            if (bitmap != null) {
                bitmap.recycle();
            }
        }


    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //设置视口

        gl.glViewport(0, 0, width, height);


        //设置当前矩阵堆栈为投影矩阵
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();

        //宽高比
        float aspect = (float) width / (float) (height == 0 ? 1 : height);

        GLU.gluPerspective(gl, 45.0f, aspect, 0.1f, 200.0f);

        GLU.gluLookAt(gl, -20, -20f, 20f, 0f, 0f, 0f, 0, 0, 1);
    }


    @Override
    public void onDrawFrame(GL10 gl) {
        //清除颜色缓冲
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        //设置当前矩阵堆栈为模型堆栈,并重置堆栈
        //即随后的矩阵操作将应用到要绘制的模型上
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0, 0, -3.0f);


        //将旋转矩阵应用到当前矩阵堆栈上,即旋转模型
        gl.glRotatef(anglez, 0, 0, 1);
        gl.glRotatef(angley, 0, 1, 0);
        gl.glRotatef(anglex, 1, 0, 0);

        anglex += 0.1;//递增角度值以便每次以不同角度绘制
        angley += 0.2;
        anglez += 0.3;

        //启用顶点数组,法向量,颜色数组
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        //设置正面
        gl.glFrontFace(GL10.GL_CW);


        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tvertices);
        //绑定纹理
        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

        //绘制triangles标识的三角形
        gl.glDrawElements(GL10.GL_TRIANGLES, triangles.remaining(), GL10.GL_UNSIGNED_BYTE, triangles);


        //禁用顶点,法向量,纹理坐标数组
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

    private int texture;
    private FloatBuffer vertices;
    private ByteBuffer triangles;
    private FloatBuffer tvertices;
    private float anglex = 0f;
    private float angley = 0f;
    private float anglez = 0f;
    private float[] data_vertices = {
            -5.0f, -5.0f, -5.0f, -5.0f,//1
            5.0f, -5.0f, 5.0f, 5.0f,
            -5.0f, 5.0f, 5.0f, -5.0f,
            5.0f, -5.0f, -5.0f, -5.0f,
            -5.0f, -5.0f,

            -5.0f, -5.0f, 5.0f, 5.0f,//2
            -5.0f, 5.0f, 5.0f, 5.0f,
            5.0f, 5.0f, 5.0f, 5.0f,
            -5.0f, 5.0f, 5.0f, -5.0f,
            -5.0f, 5.0f,

            -5.0f, -5.0f, -5.0f, 5.0f,//3
            -5.0f, -5.0f, 5.0f, -5.0f,
            5.0f, 5.0f, -5.0f, 5.0f,
            -5.0f, -5.0f, 5.0f, -5.0f,
            -5.0f, -5.0f,


            5.0f, -5.0f, -5.0f, 5.0f,//4
            5.0f, -5.0f, 5.0f, 5.0f,
            5.0f, 5.0f, 5.0f, 5.0f,
            5.0f, -5.0f, 5.0f, 5.0f,
            -5.0f, -5.0f,

            5.0f, 5.0f, -5.0f, -5.0f,//5
            5.0f, -5.0f, -5.0f, 5.0f,
            5.0f, -5.0f, 5.0f, 5.0f,
            5.0f, 5.0f, 5.0f, 5.0f,
            5.0f, -5.0f,

            -5.0f, 5.0f, -5.0f, -5.0f,
            -5.0f, -5.0f, -5.0f, -5.0f,
            5.0f, -5.0f, -5.0f, 5.0f,
            -5.0f, 5.0f, 5.0f, -5.0f,//6
            5.0f, -5.0f,
    };

    private byte[] data_triangles = {
            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[] data_tvertices = {
            1.000f, 1.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f, 1.000f, 1.000f,

            0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,

            0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,

            0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,

            0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,

            0.000f, 1.000f, 1.000f, 1.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f, 0.000f, 0.000f, 1.000f,

    };

    private void createBuffer() {

        vertices = new BufferUtil().fBuffer(data_vertices);

        //创建三角形顶点索引缓冲,索引使用byte数组,所以无须设置字节顺序,也无须写入适配
        triangles = ByteBuffer.allocate(data_triangles.length * 2);
        triangles.put(data_triangles);
        triangles.position(0);

        tvertices = new BufferUtil().fBuffer(data_tvertices);

    }

    public class BufferUtil {
        public FloatBuffer floatBuffer;

        public 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;

//            //创建顶点缓冲,顶点数组使用float类型,每个float4个字节
//            vertices = ByteBuffer.allocateDirect(data_vertices.length * 4);
//            //设置字节顺序为本机顺序
//            vertices.order(ByteOrder.nativeOrder());
//            //通过一个FloatBuffer适配器,将float数组写入ByteBuffer中
//            vertices.asFloatBuffer().put(data_vertices);
//            //重置当前buffer位置
//            vertices.position(0);
        }
    }

}

你可能感兴趣的:(android,opengl,es,android,android3d,旋转立方体)