安卓三维绘图--OpenGL ES(学习记录二)绘制三角形

OpenGL基本图形:点、线段、和三角形

如何开始?通过顶点聚合。

第一步 了解坐标系

                                                                              图1:左手坐标系与右手坐标系

其中左手坐标系广泛应用于计算机图形学、D3D之中,而右手坐标系广泛应用于OpenGL、线性代数、3DSMax之中。

先从二维入手,画一个三角形。

 第二步 定义顶点

以三角形为例,写下各个顶点数据(逆时针顺序,卷曲顺序):

private float[] mTrianglePoints = {
            -0.5f, -0.5f, 
            0.5f, -0.5f, 
            0f, 0.5f};

第三步  使数据可以被存取

OpenGL作为本地系统库是直接运行在硬件上的,在Android里,而我们的代码是运行在Dalvik(现在是ART)上,导致OpenGL无法去读取我们的数据。那么安卓虚拟机如何与OpenGL通信?

1. 使用Java本地接口(JNI)  直接调用android.opengl.GLES20

2. 把内存从Java堆复制到本地堆:改变内存分配方式
Java浮点数有32位精度,而一个字节是8位精度,每个浮点数占四个字节。

private static final int BYTES_PER_FLOAT = 4;
private final FloatBuffer mVertexData;
DrawTriangleRenderer() {
    mVertexData = ByteBuffer
            //分配本地内存,不会被垃圾回收器处理
            .allocateDirect(mTrianglePoints.length * BYTES_PER_FLOAT)
            //告诉字节缓冲区,按本地字节序组织内容
            .order(ByteOrder.nativeOrder())
            //得到反应底层字节实例
            .asFloatBuffer();

    mVertexData.put(mTrianglePoints);
}

 第四步  OpenGL管道(pipeline)

显示流程:读取顶点数据->执行顶点着色器->组装图元->光栅化图元->执行片段着色器->写入帧缓冲区->显示在屏幕上

  • 顶点着色器(Vertex Shader)顶点着色器是GPU上运行的小程序,通过它来处理顶点,他用于渲染图形顶点的OpenGL ES图形代码。顶点着色器可用来修改图形的位置,颜色,纹理坐标,不过不能用来创建新的顶点坐标。
  • 片段着色器(Fragment Shader ) 用于呈现与颜色或纹理的形状的面。每个片段是单一颜色的长方形区域,类似屏幕像素。

 

//顶点着色器
private String mVertexShaderCode =
            "attribute vec4 a_Position;     \n" +
                    "void main()                    \n" +
                    "{                              \n" +
                    "    gl_Position = a_Position;  \n" +
                    "}   \n";
//片段着色器
private String mFragmentShaderCode =
            "precision mediump float; \n" +
                    "uniform vec4 u_Color;          \n" +
                    "void main()                    \n" +
                    "{                              \n" +
                    "    gl_FragColor = u_Color;    \n" +
                    "}";

(上述代码可以保存在glsl文件中,放在res/raw目录下,然后用readTextFileFromResource()读取文本)

vec4是有四个分量的向量,可以认为是(X,Y,Z,W),XYZ对应三维坐标,W可以理解为用来透视的分量。

第五步 编译连接

创建了着色器的编译代码后,需要写个方法来执行这段代码,这里我们在渲染器中写一个如下方法来执行着色器代码

int vertexShader = compileShader(GL_VERTEX_SHADER, mVertexShaderCode);
int fragmentShader = compileShader(GL_FRAGMENT_SHADER, mFragmentShaderCode);
//连接顶点着色器和片段着色器
mShaderProgram = linkProgram(vertexShader,fragmentShader);
//告诉OpenGL绘制到屏幕上要 使用这里的程序
glUseProgram(mShaderProgram);

第六步 赋值绘制

对变量进行赋值绘制:

        //获取u_Color这个uniform的位置,存入uColorLocation
        uColorLocation = glGetUniformLocation(mShaderProgram, "u_Color");
        //获取属性的位置
        aPositionLocation = glGetAttribLocation(mShaderProgram, "a_Position");

        // 关联属性与顶点数组       
        mVertexData.position(0);//内部指针从开头读取
        glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT,
                false, 0,mVertexData);
        glEnableVertexAttribArray(aPositionLocation);

        glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);//白色

 

绘制:

    @Override
    public void onDrawFrame(GL10 glUnused) {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);//从顶点数组下标0开始,绘制3个顶点
    }

效果图

 

 

参考书籍:《OpenGL ES应用开发实践指南:Android卷》 刘力平,苏统华译


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值