1.OpenGL ES简介

OpenGL Es学习,首先要了解Android的基本架构,如下图:Android 音视频开发(五) : OpenGL ES API,了解 OpenGL 开发的基本流程,使用 OpenGL 绘制一个三角形,正方形,圆_第1张图片Android 音视频开发(五) : OpenGL ES API,了解 OpenGL 开发的基本流程,使用 OpenGL 绘制一个三角形,正方形,圆_第2张图片

 

在Android的第三层的Libraries里面就有OpenGL  ES库。OpenGL ES是一个跨平台的图形API,给3D图形处理硬件指定了一个标准的软件接口。

2.OpenGL ES在Android的使用

Android提供了两个类:GLSufaceView和GLSurfaceView.Renderer.

2.1GLSurfaceView

GlSurfaceView就是一个surfaceView ,只是增加了Render,用OpenGL来显示渲染。

2.2GLSurfaceView.Renderer

使用GLSurfaceView.setRenderer()将其附加到GLSurfaceView实例。

GLSurfaceView.Renderer要求实现以下方法:

  • onSurfaceCreated():创建GLSurfaceView时,系统调用一次该方法。使用此方法执行只需要执行一次的操作,例如设置OpenGL环境参数或初始化OpenGL图形对象。
  • onDrawFrame():系统在每次重画GLSurfaceView时调用这个方法。使用此方法作为绘制(和重新绘制)图形对象的主要执行方法。
  • onSurfaceChanged():当GLSurfaceView的发生变化时,系统调用此方法,这些变化包括GLSurfaceView的大小或设备屏幕方向的变化。例如:设备从纵向变为横向时,系统调用此方法。我们应该使用此方法来响应GLSurfaceView容器的改变。

使用GlSurfaceView步骤:

  1. 创建一个GlSurfaceView。
  2. 设置渲染
  3. 在GlSurfaceView.renderder中绘制处理显示数据

3.OpenGL ES绘制图形

在Android使用OpenGL ES的步骤:

  1. 在Manifest中声明OpenGL ES使用,我使用OpenGL ES2.0的API

    如果要使用问了要是添加

     

  2. 设置相关的渲染Renderer,Renderer有三个方法:
  • onSurfaceCreated() - 在View的OpenGL环境被创建的时候调用。
  • onDrawFrame() - 每一次View的重绘都会调用
  • onSurfaceChanged() - 如果视图的几何形状发生变化(例如,当设备的屏幕方向改变时),则调用此方法。

绘制图形

示例代码:

public class GlSurfaceViewActivity extends AppCompatActivity {private GLSurfaceView gLsurfaceview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_gl_surface_view);        gLsurfaceview = findViewById(R.id.gLsurfaceview);        gLsurfaceview.setEGLContextClientVersion(2);       // gLsurfaceview.setRenderer(new Trianglerenderer());//三角形        //gLsurfaceview.setRenderer(new SquareRenderer());//正方形        gLsurfaceview.setRenderer(new CircleRenderer());//圆        gLsurfaceview.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);    }    @Override    protected void onResume() {        super.onResume(); gLsurfaceview.onResume();    }    @Override    protected void onPause() {        super.onPause();        gLsurfaceview.onPause();    }}

三角形的Renderer:

public class Trianglerenderer extends BackgroundRender {    private int mProgram;    private FloatBuffer vertexBuffer;    private final String vertexShaderCode =            "attribute vec4 vPosition;" +                    "void main() {" +                    "  gl_Position = vPosition;" +                    "}";    private final String fragmentShaderCode =            "precision mediump float;" +                    "uniform vec4 vColor;" +                    "void main() {" +                    "  gl_FragColor = vColor;" +                    "}";    static float triangleCoords[] = {            0.0f,  0.6f, 0.0f, // top            -0.5f, -0.3f, 0.0f, // bottom left            0.5f, -0.3f, 0.0f  // bottom right    };    //设置颜色,依次为红绿蓝和透明通道    float color[] = { 0.0f, 1.0f, 0.0f, 1.0f ,            1.0f, 0.0f, 0.0f, 1.0f,            0.0f, 0.0f, 1.0f, 1.0f };    static final int COORDS_PER_VERTEX = 3;    private int mPositionHandle;    private int mColorHandle;    //顶点个数    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;    //顶点之间的偏移量    private final int vertexStride = COORDS_PER_VERTEX * 4; // 每个顶点四个字节    @Override    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {        //将背景设置为灰色        GLES20.glClearColor(0.5f,0.5f,0.5f,1.0f);        //申请底层空间        ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);        bb.order(ByteOrder.nativeOrder());        //将坐标数据转换为FloatBuffer,用以传入OpenGL ES程序        vertexBuffer = bb.asFloatBuffer();        vertexBuffer.put(triangleCoords);        vertexBuffer.position(0);        int vertexShader =  loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);        //创建一个空的OpenGLES程序        mProgram = GLES20.glCreateProgram();        //将顶点着色器加入到程序        GLES20.glAttachShader(mProgram,vertexShader);        //将片元着色器加入到程序中        GLES20.glAttachShader(mProgram,fragmentShader);        //连接到着色器程序        GLES20.glLinkProgram(mProgram);    }    @Override    public void onSurfaceChanged(GL10 gl10, int width, int height) {        GLES20.glViewport(0,0,width,height);    }    @Override    public void onDrawFrame(GL10 gl10) {        //将程序加入到OpenGLES2.0环境        GLES20.glUseProgram(mProgram);        //获取顶点着色器的vPosition成员句柄        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");        //启用三角形顶点的句柄        GLES20.glEnableVertexAttribArray(mPositionHandle);        //准备三角形的坐标数据        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,                GLES20.GL_FLOAT, false,                vertexStride, vertexBuffer);        //获取片元着色器的vColor成员的句柄        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");        //设置绘制三角形的颜色        GLES20.glUniform4fv(mColorHandle, 1, color, 0);        //绘制三角形        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);        //禁止顶点数组的句柄        GLES20.glDisableVertexAttribArray(mPositionHandle);    }}

正方形的Renderer:

public class SquareRenderer extends BackgroundRender implements GLSurfaceView.Renderer {    private FloatBuffer vertexBuffer;    private ShortBuffer indexBuffer;    private final String vertexShaderCode =            "attribute vec4 vPosition;" +                    "uniform mat4 vMatrix;" +                    "void main() {" +                    "  gl_Position = vMatrix*vPosition;" +                    "}";    private final String fragmentShaderCode =            "precision mediump float;" +                    "uniform vec4 vColor;" +                    "void main() {" +                    "  gl_FragColor = vColor;" +                    "}";    private int mProgram;    static final int COORDS_PER_VERTEX = 3;    static float triangleCoords[] = {            -0.5f, 0.5f, 0.0f, // top left            -0.5f, -0.5f, 0.0f, // bottom left            0.5f, -0.5f, 0.0f, // bottom right            0.5f, 0.5f, 0.0f  // top right    };    static short index[] = {            0, 1, 2, 0, 2, 3    };    private int mPositionHandle;    private int mColorHandle;    private float[] mViewMatrix = new float[16];    private float[] mProjectMatrix = new float[16];    private float[] mMVPMatrix = new float[16];    //顶点个数    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;    //顶点之间的偏移量    private final int vertexStride = COORDS_PER_VERTEX * 4; // 每个顶点四个字节    private int mMatrixHandler;    //设置颜色,依次为红绿蓝和透明通道    float color[] = {0.0f, 1.0f, 0.0f, 1.0f ,            1.0f, 0.0f, 0.0f, 1.0f,            0.0f, 0.0f, 1.0f, 1.0f};    @Override    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {        ByteBuffer bb = ByteBuffer.allocateDirect(                triangleCoords.length * 4);        bb.order(ByteOrder.nativeOrder());        vertexBuffer = bb.asFloatBuffer();        vertexBuffer.put(triangleCoords);        vertexBuffer.position(0);        ByteBuffer cc = ByteBuffer.allocateDirect(index.length * 2);        cc.order(ByteOrder.nativeOrder());        indexBuffer = cc.asShortBuffer();        indexBuffer.put(index);        indexBuffer.position(0);        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,                vertexShaderCode);        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,                fragmentShaderCode);        //创建一个空的OpenGLES程序        mProgram = GLES20.glCreateProgram();        //将顶点着色器加入到程序        GLES20.glAttachShader(mProgram, vertexShader);        //将片元着色器加入到程序中        GLES20.glAttachShader(mProgram, fragmentShader);        //连接到着色器程序        GLES20.glLinkProgram(mProgram);    }    @Override    public void onSurfaceChanged(GL10 gl10, int width, int height) {        //计算宽高比        float ratio = (float) width / height;        //设置透视投影        Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 7);        //设置相机位置        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 7.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);        //计算变换矩阵        Matrix.multiplyMM(mMVPMatrix, 0, mProjectMatrix, 0, mViewMatrix, 0);    }    @Override    public void onDrawFrame(GL10 gl10) {        //将程序加入到OpenGLES2.0环境        GLES20.glUseProgram(mProgram);        //获取变换矩阵vMatrix成员句柄        mMatrixHandler = GLES20.glGetUniformLocation(mProgram, "vMatrix");        //指定vMatrix的值        GLES20.glUniformMatrix4fv(mMatrixHandler, 1, false, mMVPMatrix, 0);        //获取顶点着色器的vPosition成员句柄        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");        //启用三角形顶点的句柄        GLES20.glEnableVertexAttribArray(mPositionHandle);        //准备三角形的坐标数据        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,                GLES20.GL_FLOAT, false,                vertexStride, vertexBuffer);        //获取片元着色器的vColor成员的句柄        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");        //设置绘制三角形的颜色        GLES20.glUniform4fv(mColorHandle, 1, color, 0);        //绘制三角形//        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);        //索引法绘制正方形        GLES20.glDrawElements(GLES20.GL_TRIANGLES, index.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);        //禁止顶点数组的句柄        GLES20.glDisableVertexAttribArray(mPositionHandle);    }}

圆的Renderer:

public class CircleRenderer extends BackgroundRender implements GLSurfaceView.Renderer {    String vertexShaderCode = "attribute vec4 vPosition;\n" +            "uniform mat4 vMatrix;\n" +            "void main() {\n" +            "  gl_Position = vMatrix*vPosition;\n" +            "}" ;    String fragmentShaderCode = "precision mediump float;\n" +            " uniform vec4 vColor;\n" +            " void main() {\n" +            "     gl_FragColor = vColor;\n" +            " }";    int mProgram;    private FloatBuffer vertexBuffer;    private float[] circlrCoods;    float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //顶点统一白色    public CircleRenderer() {        //设置所有坐标        circlrCoods = createPositions();        //float[] → FloatBuffer        ByteBuffer bb = ByteBuffer.allocateDirect(circlrCoods.length * 4);        bb.order(ByteOrder.nativeOrder());        vertexBuffer = bb.asFloatBuffer();        vertexBuffer.put(circlrCoods);        vertexBuffer.position(0);    }    private float[]  createPositions(){        ArrayList data=new ArrayList<>();        data.add(0.0f);             //设置圆心坐标        data.add(0.0f);        data.add(0.0f);        //分成100条边,绘制出来应该很像圆了        float radius = 0.5f; //半径1        float angDegSpan=360f/100; //依次递加的角度        for(float i=0;i<360+angDegSpan;i+=angDegSpan){            data.add((float)(radius*Math.cos(i*Math.PI/180f))); //x            data.add((float) (radius*Math.sin(i*Math.PI/180f))); //y            data.add(0.0f); //z        }        float[] f=new float[data.size()];        for (int i=0;i


项目地址:https://github.com/ChloeDimen/AudioAndVideo

 

更多相关文章

  1. c语言如何求三角形的面积
  2. 手把手教你在C语言中如何打印倒三角形
  3. 图解两数之和的变形题之「有效三角形的个数」
  4. 如何为每个JQuery UI滑块句柄使用不同的图像
  5. 从“顶点小说”下载完整小说——python爬虫
  6. Python能不能方便的画三角形?
  7. python输出斐波那契数列三角形
  8. java三角形的画法

随机推荐

  1. android studio 0.80多渠道打包
  2. adb server is out of date. killing...
  3. 【Android UI】ViewPager禁止滚动
  4. android实现图片模糊背景效果
  5. Android网络状态监听
  6. Android 通知栏Notification 悬浮通知栏
  7. android 版本及对应数值
  8. “Debug certificate expired” error
  9. Android如何导入已有的外部数据库
  10. Android连接到加密网络