美文网首页
OpenGL ES 绘制立方体

OpenGL ES 绘制立方体

作者: simple_0955 | 来源:发表于2018-02-08 10:48 被阅读0次
    立方体.png

    public class EGLView extends GLSurfaceView {
    public EGLView(Context context) {
    super(context);
    init();
    }

    private void init() {
        setEGLContextClientVersion(2);
        Renderer renderer = new Renderer();
        setRenderer(renderer);
        setRenderMode(RENDERMODE_CONTINUOUSLY);
    }
    

    public class Renderer implements GLSurfaceView.Renderer {
    Cube cube;
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    //设置背景颜色
    GLES20.glClearColor(0.5f,0.5f,0.5f,0.5f);
    //开启深度测试
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    cube=new Cube();
    }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            //设置视口
            GLES20.glViewport(0,0,width,height);
            //计算宽高比
            float r=(float) width/height;
            //计算透视投影
            Matrix.frustumM(Cube.mProjMatrix,0,-r,r,-1,1,3,20);
            //设置相机位置
            Matrix.setLookAtM(Cube.mVMatrix,0,
                    5f,5f,10, //相机位置
                    0f,0f,0f, //目标位置
                    1f,1f,0f);//up位置
    
        }
    
        @Override
        public void onDrawFrame(GL10 gl) {
            //清除颜色很深度缓存
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);
            //绘制
            cube.drawSelf();
        }
    }
    

    }

    public class Cube extends Utils {
    private FloatBuffer verBuffer;
    private FloatBuffer colorBuffer;
    private ShortBuffer intdexBuffer;
    private int mProgram;
    private int vPosition, aColor;
    private int vMatrix;

    public Cube() {
        initData();
        initShader();
    }
    
    private void initData() {
        //顶点
        verBuffer = getFloatBuffer(cubePositions);
        //颜色
        colorBuffer = getFloatBuffer(color);
        //所有
        intdexBuffer = getShortBuffer(intdex);
    }
    
    private void initShader() {
    
        //创建程序
        mProgram = GLES20.glCreateProgram();
        //管理着色器源码
        GLES20.glAttachShader(mProgram, loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode));
        GLES20.glAttachShader(mProgram, loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode));
        //连接程序
        GLES20.glLinkProgram(mProgram);
        //获取GLSL的变量id
        vPosition = GLES20.glGetAttribLocation(mProgram, "vPosition");
        aColor = GLES20.glGetAttribLocation(mProgram, "aColor");
        vMatrix = GLES20.glGetUniformLocation(mProgram, "vMatrix");
    
    }
    
    // 设置矩阵变换的所用到的矩阵
    public static float[] mProjMatrix = new float[16];//4x4矩阵 投影用
    public static float[] mVMatrix = new float[16];//摄像机位置朝向9参数矩阵
    public static float[] mMVPMatrix;//最后起作用的总变换矩阵
    public static float[] mMMatrix = new float[16];//具体物体的移动旋转矩阵,旋转、平移
    public float xAngle = 0;//绕x轴旋转的角度
    
    //绘制
    public void drawSelf() {
        //加载到OpenGL ES环境中
        GLES20.glUseProgram(mProgram);
        //变换矩阵
        Matrix.setRotateM(mMMatrix, 0, 0, 0, 1, 0);
        //位移 z轴正向位移
        Matrix.translateM(mMMatrix, 0, 0, 0, 1);
        //旋转Z轴正向位移
        Matrix.rotateM(mMMatrix, 0, xAngle, 1, 1, 1);
        //给glsl变量赋值
        GLES20.glUniformMatrix4fv(vMatrix, 1, false, getMatrix(mMMatrix), 0);
        //设置数据
        GLES20.glVertexAttribPointer(vPosition, 3, GLES20.GL_FLOAT, false, 0, verBuffer);
        GLES20.glVertexAttribPointer(aColor, 4, GLES20.GL_FLOAT, false, 0, colorBuffer);
        //开启顶点和颜色
        GLES20.glEnableVertexAttribArray(vPosition);
        GLES20.glEnableVertexAttribArray(aColor);
        //绘制
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, intdexBuffer);
    
    }
    
    //矩阵相乘操作
    public float[] getMatrix(float[] spec) {
        mMVPMatrix = new float[16];
        //位移操作
        Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, spec, 0);
        //合并投影和视口矩阵
        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
        return mMVPMatrix;
    }
    
    ;
    

    }

    public abstract class Utils {
    /**
    * 顶点坐标
    /
    public float[] cubePositions = {
    -1f, 1f, 1f,
    -1f, -1f, 1f,
    1f, -1f, 1f,
    1f, 1f, 1f,
    -1f, 1f, -1f,
    -1f, -1f, -1f,
    1f, -1f, -1f,
    1f, 1f, -1f
    };
    //6个面,一个面六个点
    public short intdex[]={
    6,7,4,6,4,5,
    6,3,7,6,2,3,
    6,5,1,6,1,2,
    0,3,2,0,2,1,
    0,1,5,0,5,4,
    0,7,3,0,4,7
    };
    public float color[] = {
    // (1111代表白色)颜色排列:RGB A
    1f, 1f, 1f, 1f,
    0f, 1f, 0f, 1f,
    1f, 1f, 0f, 1f,
    1f, 0f, 1f, 1f,
    0f, 0f, 1f, 1f,
    0f, 0f, 0.5f, 1f,
    1f, 1f, 1f, 1f,
    0.5f, 0f, 0f, 1f,
    };
    /
    *
    * 顶点着色器
    /
    public final String vertexShaderCode =
    "attribute vec4 vPosition;" +//声明一个用attribute修饰的变量(顶点)
    "uniform mat4 vMatrix;" +//总变换矩阵
    "varying vec4 vColor;" +//颜色易变变量(成对出现)
    "attribute vec4 aColor;" +//声明一个用attribute修饰的变量(颜色)
    "void main() {" +
    " gl_Position = vMatrix
    vPosition;" +//根据总变换的矩阵计算绘制此顶点的位置
    " vColor=aColor;" + //将接收的颜色传递给片元着色器
    "}";
    /**
    * @Effect 片段着色器;
    */
    public final String fragmentShaderCode =
    // 片元语言没有默认浮点精度修饰符
    // 因此,对于浮点数,浮点数向量和矩阵变量声明,
    // 要么声明必须包含一个精度修饰符,要么不默认精度修饰符在之前 已经被声明过。
    "precision mediump float;" +//预定义的全局默认精度
    "varying vec4 vColor;" +//接收从顶点着色器过来的参数
    "void main() {" +
    " gl_FragColor = vColor;" + //给此片源颜色值
    "}";

    /**
     * @param shaderType(着色器类型,顶点和片元);
     * @param shaderCode(着色器代码);
     * @return 返回着色器对象
     * @Effect 加载Shader的方法;
     */
    public int loadShader(int shaderType, String shaderCode) {
        //根据type创建顶点着色器或者片元着色器
        int shader = GLES20.glCreateShader(shaderType);
        //将资源加入到着色器中,并编译
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);
        return shader;
    }
    
    
    /**
     * @param ver_Tex(数组,一般为顶点数据);
     * @return Float型缓冲
     * @Effect 获取FloatBuffer数据缓冲;
     */
    public FloatBuffer getFloatBuffer(float ver_Tex[]) {
        //创建顶点坐标数据缓冲
        // vc.length*4是因为一个整数四个字节
        ByteBuffer bb = ByteBuffer.allocateDirect(ver_Tex.length * 4);
        //设置字节顺序
        // 由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer转换
        bb.order(ByteOrder.nativeOrder());
        //转换为Float型缓冲
        FloatBuffer vertexBuffer = bb.asFloatBuffer();
        //向缓冲区中放入顶点坐标数据
        vertexBuffer.put(ver_Tex);
        //设置缓冲区起始位置
        vertexBuffer.position(0);
        return vertexBuffer;
    }
    
    /**
     * @param index(这个是绘制顶点的索引数组);
     * @return Short型缓冲
     * @Effect 获取ShortBuffer数据缓冲;
     */
    public ShortBuffer getShortBuffer(short index[]) {
        ByteBuffer cc = ByteBuffer.allocateDirect(index.length * 2);
        cc.order(ByteOrder.nativeOrder());
        ShortBuffer indexBuffer = cc.asShortBuffer();
        indexBuffer.put(index);
        indexBuffer.position(0);
        return indexBuffer;
    }
    

    }

    相关文章

      网友评论

          本文标题:OpenGL ES 绘制立方体

          本文链接:https://www.haomeiwen.com/subject/ufnzzxtx.html