Android OpenGL ES开发(三)绘制一个三角形

1、前言

选择绘制三角形作为OpenGL ES的第一个实例,是因为点、线、三角形是OpenGL ES世界的图形基础,无论多么复杂的几何物体,在OpenGL ES的世界里都可以用三角形拼成

2、步骤

依照官方文档中的说明,Android中利用OpenGL ES 2.0绘制三角形的步骤为:

2.1在AndroidManifest.xml文件中设置使用的OpenGL ES的版本:


GLSurfaceView glv = findViewById(R.id.glv);
//必须代码设置版本
 glv.setEGLContextClientVersion(2);

2.2毫无疑问的,显示三角形,需要一个载体。创建显示三角形的Activity,利用GLSurfaceView作为显示三角形的View,图形的具体渲染工作都是在Render中完成的。

3. 实现GLSurfaceView的Render,在Render中完成三角形的绘制,具体行为有:

1、加载顶点和片元着色器
2、确定需要绘制图形的坐标和颜色数据
3、创建program对象,连接顶点和片元着色器,链接program对象。
4、设置视图窗口(viewport)。
5、将坐标数据颜色数据传入OpenGL ES程序中
6、使颜色缓冲区的内容显示到屏幕上。

3、具体实现

我们设置好OpenGL ES版本、创建入口Activity并设置好GLSurfaceView做为显示载体后,就进入了我们最主要的工作了。

3.1 第一步

首先,我们需要编写一个简单的顶点着色器和一个简单的片元着色器:
顶点着色器:

    private final String vertextShaderCode =
            "attribute vec4 vPosition;"+
            "void main() {"+
            "   gl_Position = vPosition;"+
            "}";

片元着色器:

    private final String fragmentShaderCode =
            "precision mediump float;"+
            "uniform vec4 vColor;"+
            "void main() {"+
            "   gl_FragColor = vColor;"+
            "}";

gl_Position和gl_FragColor都是Shader的内置变量,分别为定点位置和片元颜色。

3.2 第二步

然后,我们确定要绘制的图形的顶点坐标和颜色:
我们现在需要绘制的是在一个三维空间中绘制一个三角形,三角形当然是三个顶点了。因为我们三角形只是一个平面图形。为了方便,我们现在在不设置相机(相机在后面讲)的情况下,三角形正对我们来呈现。所以我们打三个顶点的Z坐标都设置为0。OpenGL ES坐标映射到屏幕上,从屏幕中心垂直到上下左右边缘距离都是1.0,所以(-1.0,0,0)和(0,1.0,0)到原点的距离在屏幕上呈现出来的结果是不一样的,图解如下(左边是理想状态,右边是实际状态):


1.png

所以,为了不超出屏幕,我们的坐标数据设置为:

    private float triangleCoors[] = {
            0.5f , 0.5f , 0.0f,
            -0.5f , -0.5f , 0.0f,
            0.5f , -0.5f , 0.0f
    };

颜色数据,我们设置为单一颜色:

    private float color[] = {
            1.0f , 1.0f , 1.0f , 1.0f
    };

3.3 第三步

接着我们开始在Render中实现我们的三角形绘制了。Render接口有三个方法,分别为

onSurfaceCreated
onSurfaceChanged
onDrawFrame

在onSurfaceCreated方法中,我们来创建program对象,连接顶点和片元着色器,链接program对象。

        //设置背景颜色
        GLES20.glClearColor(0.5f,0.5f,0.5f,0.5f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        //申请底层空间
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(triangleCoors.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        //将坐标数据转换为FloatBuffer,用以传入给OpenGL ES程序
        vertexBuffer = byteBuffer.asFloatBuffer();
        //将三角形坐标传入FloatBuffer
        vertexBuffer.put(triangleCoors);
        vertexBuffer.position(0);
        //创建顶点着色器程序
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertextShaderCode);
        //创建片元着色器程序
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

        if (vertexShader == 0 || fragmentShader == 0)
        {
            return;
        }
        //创建一个空的OpenGL ES程序
        program = GLES20.glCreateProgram();
        //将顶点着色器加入程序
        GLES20.glAttachShader(program, vertexShader);
        //将片元着色器加入程序
        GLES20.glAttachShader(program, fragmentShader);
        //连接到着色器程序中
        GLES20.glLinkProgram(program);
        //将程序加入到OpenGLES2.0环境
        GLES20.glUseProgram(program);
    public int loadShader(int type , String shaderCode)
    {
        //创建空的着色器
        int shader = GLES20.glCreateShader(type);
        //将着色器程序加到着色器中
        GLES20.glShaderSource(shader,shaderCode);
        //编译色器程序
        GLES20.glCompileShader(shader);

        return shader;

    }

3.4 第四步

在onSurfaceChanged中设置视图窗口:

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

3.5 第五步

最后在onDrawFrame中绘制

        if(program == 0)
            return;

        //获取顶点着色器的vPosition成员句柄
        int vPosition = GLES20.glGetAttribLocation(program, "vPosition");
        //启用vPosition句柄
        GLES20.glEnableVertexAttribArray(vPosition);
        //传入但侥幸的坐标数据
        GLES20.glVertexAttribPointer(vPosition,3,GLES20.GL_FLOAT,false,3*4, vertexBuffer);
        //获取片元着色器的vColor成员句柄
        int vColor = GLES20.glGetUniformLocation(program, "vColor");
        //设置绘制三角形的颜色
        GLES20.glUniform4fv(vColor,1,color,0);
        //绘制三角形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3);
        //禁止顶点数组的句柄
        GLES20.glDisableVertexAttribArray(vPosition);

你可能感兴趣的:(Android OpenGL ES开发(三)绘制一个三角形)