Android OpenGl ES2.0编程_相关概念与绘制顶点

前言
前面介绍了使用 Android 编写 OpenGL ES 应用的程序框架,并成功绘制了第一个OpenGL ES 2.0的小程序,本篇介绍 3D 绘图的一些基本构成要素,基本概念,重要的函数,最终将实现一个顶点的绘制。
本文是建立在上一篇文章之上,只修改MyRenderer类,其他部分保持不变,如果你没有看上一篇文章,请先移步Android OpenGl ES2.0编程_第一个OpenGL小程序

▲ 基本概念

Vertex (顶点)
顶点是3D建模时用到的最小构成元素,顶点定义为两条或是多条边交会的地方。在 3D 模型中一个顶点可以为多条边,面或是多边形所共享。一个顶点也可以代表一个点光源或是 Camera 的位置。下图中标识为黄色的点为一个顶点(Vertex)。

三维坐标系

三维笛卡儿坐标系是在二维笛卡儿坐标系的基础上根据右手定则增加第三维坐标(即Z轴)而形成的。同二维坐标系一样,AutoCAD中的三维坐标系有世界坐标系WCS(World Coordinate System)和用户坐标系UCS(User Coordinate System)两种形式。---百度百科

学习OpenGL编程,少不了需要了解坐标系的概念,这里我们不用理解的那么深,简单的知道和了解最基本的就好,推荐阅读三维坐标系介绍

在3D绘图中,坐标轴遵循右手法则。三维坐标系中,Z轴的正轴方向是根据右手定则确定的。右手定则也决定三维空间中任一坐标轴的正旋转方向。
要标注X、Y和Z轴的正轴方向,就将右手背对着屏幕放置,拇指即指向X轴的正方向。伸出食指和中指,如右图所示,食指指向Y轴的正方向,中指所指示的方向即是Z轴的正方向。
要确定轴的正旋转方向,如右图所示,用右手的大拇指指向轴的正方向,弯曲手指。那么手指所指示的方向即是轴的正旋转方向。

▲ 点的构成
有了之前对坐标系的理解,我们知道,在3D绘制中,一个点包含x、y、z坐标。在Android系统中,可以用一个float数组、int数组等来表示一个点。如下:

private float[] mArrayVertex = { 0f, 0f, 0f };

为了提高性能,通常将这些数组存放到 java.io 中定义的 Buffer 类中
新建一个工具类ToolUtils,把获取Buffer数据的代码封装如下

public class ToolUtils {
    /**
     * @param vertexes float 数组
     * @return 获取浮点形缓冲数据
     */
    public static FloatBuffer getFloatBuffer(float[] vertexes) {
        FloatBuffer buffer;
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertexes.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        buffer = vbb.asFloatBuffer();
        //写入数组
        buffer.put(vertexes);
        //设置默认的读取位置
        buffer.position(0);
        return buffer;
    }
}

▲ 绘制一个点
这里只需修改MyRenderer类的代码,其余代码和之前搭建的基础框架一样。MyRenderer.java

public class MyRenderer implements GLSurfaceView.Renderer {
    //顶点数组
    private float[] mArrayVertex = { 0f, 0f, 0f };

    // 缓冲区
    private FloatBuffer mBuffer;

    MyRenderer() {
        //获取浮点形缓冲数据
        mBuffer = ToolUtils.getFloatBuffer(mArrayVertex);
    }

    // Surface创建的时候调用
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 设置清屏颜色为黑色(rgba)
        gl.glClearColor(0f, 0f, 0f, 0f);
    }

    // Surface改变的的时候调用
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 设置OpenGL场景的大小
        gl.glViewport(width / 4, width / 2, width / 2, height / 2);
    }

    // 在Surface上绘制的时候调用
    @Override
    public void onDrawFrame(GL10 gl) {

        // 清除屏幕
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        // 允许设置顶点 // GL10.GL_VERTEX_ARRAY顶点数组
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // 设置顶点
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBuffer);

        //设置点的颜色为红色
        gl.glColor4f(1f, 0f, 0f, 0f);

        //设置点的大小
        gl.glPointSize(100f);

        // 绘制点
        gl.glDrawArrays(GL10.GL_POINTS, 0, 1);

        // 禁止顶点设置
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }
}

▲ 启用相关功能及配置说明
这里讲解部分比较重要的函数,之后还有一些常用API在之后的文章会重点讲到

0. glClearColor()
设置清屏颜色,每次清屏时,使用该颜色填充整个屏幕。里面参数分别代表RGBA,取值范围为[0,1]而不是[0,255]。例如:

gl.glClearColor(0f, 0f, 0f, 0f);

1. glVertexPointer()
设置一个指针,这个指针指向顶点数组,后面绘制三角形(或矩形)根据这里指定的顶点数组来读取数据
函数原型:

void glVertexPointer(int size,int type,int stride,Buffer pointer)

参数解释

size —— 每个顶点的坐标维数,必须是2, 3 或者4,初始值是4。

type —— 指明每个顶点坐标的数据类型,允许的符号常量GL_BYTE, GL_SHORT,GL_FIXED 和GL_FLOAT,初始值为GL_FLOAT。

stride —— 指明连续顶点间的位偏移,如果为0,顶点被认为是紧密压入矩阵,初始值为0。

pointer —— 指明顶点坐标的缓冲区,如果为null,则没有设置缓冲区。

2. glClear()
用来清理缓冲区,并设置为预设值
函数原型:

glClear(int mask)

mask的值有以下三种

GL_COLOR_BUFFER_BIT —— 表明颜色缓冲区

GL_DEPTH_BUFFER_BIT —— 表明深度缓冲

GL_STENCIL_BUFFER_BIT —— 表明模型缓冲区

3. glEnableClientState()
启用客户端的某项功能。glEnableClientState和glDisableClientState启用或禁用客户端的单个功能。默认的,所有客户端功能禁用。 array可以是下列符号常量:

GL_COLOR_ARRAY —— 如果启用,颜色矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glColorPointer。

GL_NORMAL_ARRAY —— 如果启用,法线矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glNormalPointer。

GL_TEXTURE_COORD_ARRAY —— 如果启用,纹理坐标矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glTexCoordPointer。

GL_VERTEX_ARRAY —— 如果启用,顶点矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染。详见glVertexPointer。

GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)——如果启用,点大小矩阵控制大小以渲染点和点sprites。这时由glPointSize定义的点大小将被忽略,由点大小矩阵 提供的大小将被用来渲染点和点sprites。详见glPointSize。

4. glDrawArrays()
绘制数组里面所有点构成的各个三角片
函数原型:

void glDrawArrays(
    int mode,
    int first,
    int count
);

参数解释

mode:有三种取值

  • GL_TRIANGLES:每三个顶之间绘制三角形,之间不连接
  • GL_TRIANGLE_FAN:以V0 V1 V2,V0 V2 V3,V0 V3 V4,……的形式绘制三角形
  • GL_TRIANGLE_STRIP:顺序在每三个顶点之间均绘制三角形。这个方法可以保证从相同的方向上所有三角形均被绘制。以V0 V1 V2 ,V1 V2 V3,V2 V3 V4,……的形式绘制三角形

first:从数组缓存中的哪一位开始绘制,一般都定义为0

count:顶点的数量

▲ 最终效果图
看着虽然是一个正方形,但实际它是一个大小为100f的正方形的点

▲ 完整代码下载:https://github.com/ChenYXin/OpenGL_ES_2.0_Sample

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容