注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接:http://developer.android.com/training/graphics/opengl/shapes.html


在一个OpenGL ES视图的上下文中定义形状,是创建你的杰作所需要的第一步。在不知道关于OpenGL ES如何期望你来定义图形对象的基本知识的时候,通过OpenGL ES 绘图可能会有些困难。

这节课将解释OpenGL ES相对于Android设备屏幕的坐标系,定义形状和形状表面的基本知识,如定义一个三角形和一个矩形。


一). 定义一个三角形

OpenGL ES允许你使用三维空间的坐标来定义绘画对象。所以在你能画三角形之前,你必须先定义它的坐标。在OpenGL 中,典型的办法是以浮点数的形式为坐标定义一个顶点数组。为了让效率最大化,你可以将坐标写入一个ByteBuffer,它将会传入OpenGl ES的图形处理流程中:

public class Triangle {    private FloatBuffer vertexBuffer;    // number of coordinates per vertex in this array    static final int COORDS_PER_VERTEX = 3;    static float triangleCoords[] = {   // in counterclockwise order:             0.0f,  0.622008459f, 0.0f, // top            -0.5f, -0.311004243f, 0.0f, // bottom left             0.5f, -0.311004243f, 0.0f  // bottom right    };    // Set color with red, green, blue and alpha (opacity) values    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };    public Triangle() {        // initialize vertex byte buffer for shape coordinates        ByteBuffer bb = ByteBuffer.allocateDirect(                // (number of coordinate values * 4 bytes per float)                triangleCoords.length * 4);        // use the device hardware's native byte order        bb.order(ByteOrder.nativeOrder());        // create a floating point buffer from the ByteBuffer        vertexBuffer = bb.asFloatBuffer();        // add the coordinates to the FloatBuffer        vertexBuffer.put(triangleCoords);        // set the buffer to read the first coordinate        vertexBuffer.position(0);    }}

默认情况下,OpenGL ES会假定一个坐标系,在这个坐标系中,[0, 0, 0](X, Y, Z)对应的是GLSurfaceView框架的中心。[1, 1, 0]对应的是框架的右上角,[-1, -1, 0]对应的则是左下角。如果想要看此坐标系的插图说明,可以阅读OpenGL ES开发手册。

注意到这个形状的坐标是以逆时针顺序定义的。绘制的顺序非常关键,因为它定义了那一面是形状的正面(你希望绘制的一面),以及背面(你可以使用OpenGL ES的cull face特性来让它不要绘制)。更多关于该方面的信息,可以阅读OpenGL ES开发手册。


二). 定义一个矩形

在OpenGL中定义三角形非常简单,那么你是否想要增加一些复杂性呢?比如,定义一个矩形?有很多方法可以用来定义矩形,不过在OpenGL ES中最典型的办法是使用两个三角形拼接在一起:

图1. 使用两个三角形画一个矩形

再一次地,你需要以逆时针的形式为三角形顶点定义坐标来表现这个图形,并将值放入一个ByteBuffer中。为了避免由两个三角形共享的顶点被重复定义,可以使用一个绘制列表来告诉OpenGL ES图形处理流程应该如何画这些顶点。下面是代码样例:

public class Square {    private FloatBuffer vertexBuffer;    private ShortBuffer drawListBuffer;    // number of coordinates per vertex in this array    static final int COORDS_PER_VERTEX = 3;    static float squareCoords[] = {            -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    private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices    public Square() {        // initialize vertex byte buffer for shape coordinates        ByteBuffer bb = ByteBuffer.allocateDirect(        // (# of coordinate values * 4 bytes per float)                squareCoords.length * 4);        bb.order(ByteOrder.nativeOrder());        vertexBuffer = bb.asFloatBuffer();        vertexBuffer.put(squareCoords);        vertexBuffer.position(0);        // initialize byte buffer for the draw list        ByteBuffer dlb = ByteBuffer.allocateDirect(        // (# of coordinate values * 2 bytes per short)                drawOrder.length * 2);        dlb.order(ByteOrder.nativeOrder());        drawListBuffer = dlb.asShortBuffer();        drawListBuffer.put(drawOrder);        drawListBuffer.position(0);    }}

该样例给了你一个如何使用OpenGL创建复杂图形的启发,通常来说,你需要使用三角形的集合来绘制对象。在下一节课中,你将学习如何在屏幕上画这些形状。

更多相关文章

  1. 理解Android中的自定义属性
  2. Android(安卓)自定义 MarqueeView 实现跑马灯 —— 原理篇
  3. Android三方库依赖中的maven坐标详解
  4. 【ArcGIS for Android】使用自定义Callout显示地图信息
  5. android 8.0 自定义控件onmesure获取宽度为0
  6. 定义Window进入和退出效果(及Window,Activity,View的理解)
  7. android web services2
  8. 2011年Android(安卓)MediaPlayer学习笔记之一
  9. 【Android(安卓)Developers Training】 98. 获取联系人列表

随机推荐

  1. 20201230 pyc是什么
  2. 20201225 字典的使用
  3. 20201224 字符串常用操作
  4. 20210111 装饰器之案例剖析
  5. 20210108 装饰器详解
  6. Vue自学之路3-vue模版初探
  7. 20210104 递归
  8. 210329 CSS 媒体查询 grid布局
  9. 大数据技术完美地解决了海量数据问题,可为
  10. DolphinDB的权限管理和安全