OpenGL ES 绘制三角形(二)

本文介绍了如何使用OpenGLES编写代码来绘制一个基本的三角形。首先讲解了顶点着色器和片元着色器的作用,分别用于确定形状和颜色。接着展示了顶点着色器和片元着色器的源码,然后阐述了如何创建、编译和链接这两个着色器。最后,详细解释了如何设置顶点数据、颜色以及调用`glDrawArrays`进行绘制。通过这个过程,读者可以了解到OpenGLES的基本绘图流程。
摘要由CSDN通过智能技术生成

在上一篇博客我们简单的搭建了一个OpenGL ES的框架,本节让我们看看如何编写OpenGL ES 代码绘制一个简单的三角形吧。

首先 我们编写顶点着色器和片元着色器

顶点着色器(Vertex Shader) 用来确定形状。
片元着色器(Fragment Shader)用来确定颜色

着色器代码,如下:

    //顶点着色器
    public static final String VERTEX_SHADER_SOURCE ="" +
            "attribute vec4 vPosition;\n" +
            "void main(){\n" +
            "    gl_Position = vPosition;\n" +
            "}";

    //片元着色器
    public static final String FRAGMENT_SHADER_SOURCE = "" +
            "precision mediump float;\n" +
            "uniform vec4 fColor;\n" +
            "void main() {\n" +
            "    gl_FragColor = fColor;\n" +
            "}";

上面就是最简单的着色器代码了,就是两段字符串。当然你也可以写在单独的文件中,然后编写工具类加载成String。

  • 首先分析顶点着色器
    1、attribute 属性变量,只能用在顶点着色器,用来将数据由应用程序传输给顶点着色器
    2、vec4是数据类型,表示包含4个浮点型数据的向量
    3、vPosition就是我们自己定义的变量了。
    4、gl_Position 是顶点着色器内置变量,表示顶点着色器中顶点位置。

通常我们在应用程序中把位置传给vPosition变量,在由vPosition变量传给gl_Position,这样顶点位置就确定了。

  • 接着分析片元着色器
    1、precision mediump 是精度,在片元着色器中使用浮点类型数据,必须指定其精度。precision lowp 低精度、precision mediump 中精度、precision highp 高精度。
    2、uniform 一致变量,着色器执行期间一致变量的值是不变的
    3、gl_FragColor: vec4类型,片元着色器内置变量,表示片元颜色

我们在应用程序中把颜色传给我们自己定义的fColor变量,在由fColor变量传给gl_FragColor,这样颜色就确定了。

着色器创建好了,接着需要使用它们。

        //创建顶点着色器,vShader是创建的着色器的句柄
        int vShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        //设置着色器的源码
        GLES20.glShaderSource(vShader, VERTEX_SHADER_SOURCE);
        //编译代码
        GLES20.glCompileShader(vShader);

        //创建片元着色器
        int fShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        //设置着色器的源码
        GLES20.glShaderSource(fShader, FRAGMENT_SHADER_SOURCE);
        //编译
        GLES20.glCompileShader(fShader);

        //创建程序
        glProgram = GLES20.glCreateProgram();
        //将两个着色器添加到程序中
        GLES20.glAttachShader(glProgram,vShader);
        GLES20.glAttachShader(glProgram,fShader);
        //链接程序
        GLES20.glLinkProgram(glProgram);

GLES20.glCreateShader() 创建一个着色器对象,方法的参数可以是GL_VERTEX_SHADER 和或GL_FRAGMENT_SHADER ,代表是创建顶点着色器还是片元着色器,方法的返回值可以理解为着色器的指针或者句柄。
经过上面的代码,我们将创建好了opengl es 程序对象了,并且把我们的着色器添加进去,并且进行了链接,接着我们就可以使用该程序。

    public void draw() {
        //加载并使用链接好的程序
        GLES20.glUseProgram(glProgram);
        //获取指定名称的attribute变量位置
        int vPositionLocation = GLES20.glGetAttribLocation(glProgram, "vPosition");
        //允许使用顶点坐标数组
        GLES20.glEnableVertexAttribArray(vPositionLocation);
        //将顶点数据赋值到指定属性
        GLES20.glVertexAttribPointer(vPositionLocation, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                0, vertexBuffer);
        //获取指定名称的uniform变量位置
        int fColorLocation = GLES20.glGetUniformLocation(glProgram, "fColor");
        //给指定的Uniform变量赋值 因为color包含4个值所以调用glUniform4fv
        GLES20.glUniform4fv(fColorLocation,1,color,0);

        //绘制
        //GL_TRIANGLES会是三角形  0:告诉 OpenGL 从顶点数组的开头处开始读顶点,vertexCount:告诉 OpenGL 读入vertexCount个顶点
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,vertexCount);
        //禁用指定顶点属性
        GLES20.glDisableVertexAttribArray(vPositionLocation);
        GLES20.glUseProgram(GLES20.GL_NONE);
    }

glVertexAttribPointer(
int indx,//我们要修改的顶点属性的位置
int size,//每个顶点属性组件的数量,这里传入3,每个顶点由(x,y,z)组成
int type,//每个组件的数据类型
boolean normalized,//是否归一化处理
int stride,//指定连续顶点属性之间的偏移量,偏移量0表示精密排列
java.nio.Buffer ptr//顶点数据
)

glDrawArrays(
int mode,//GL_TRIANGLES 绘制三角形
int first,// 0:告诉 OpenGL 从顶点数组的开头处开始读顶点
int count // 读入几个顶点
);

接下来就是确定顶点数据
在这里插入图片描述
上图是二维坐标系,事实上opengles 坐标系是三维的 还有一个z轴我没有画。
我们要在这样一个坐标系中绘制一个三角形,如图
在这里插入图片描述
这样我们就确定了顶点位置了。

//顶点位置
static float[] triangle = {
            -0.5f,-0.5f,0f,
            0.5f,-0.5f,0f,
            0f,0.5f,0f
    };
//每个顶点三个组件组成(x,y,z)
private int COORDS_PER_VERTEX = 3;
//顶点数量,三角形 三个点
private final int vertexCount = triangle.length / COORDS_PER_VERTEX;

最后还需要颜色

//颜色:R,G,B,A
    static float[] color = {
            1.0f,0.0f,0f,1f
    };

github代码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值