zoukankan      html  css  js  c++  java
  • 使用Android OpenGL ES 2.0绘图之二:定义形状

    传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

             在OpenGLES view上能够定义所绘制图形的形状,是创建高端图形应用杰作的第一步。如果你不懂得OpenGL ES定义图形对象的一些基本知识,那么使用起来可能有一点棘手。

            这一节将介绍OpenGL ES相对于Android设备屏幕的坐标系,定义一个形状的基础知识,形状的外观,以及如何定义一个三角形和一个正方形。

    1定义一个三角形

            OpenGL ES允许你使用三维空间坐标系来定义绘制对象。所以,在你想要绘制一个三角形之前,必须定义它的坐标。

             在OpenGL中,典型的方式是定义一个浮点类型的顶点数组存放各个顶点坐标。为了获得更高的效率,应该将这些坐标都存放到一个ByteBuffer中,ByteBuffer会被传入OpenGL ES图形管道进行处理。
    class Triangle {
    
        private FloatBuffer vertexBuffer;
    
        // 设置每个顶点的坐标数
        static final int COORDS_PER_VERTEX = 3;
        // 设置三角形顶点数组
        static float triangleCoords[] = { // 默认按逆时针方向顺序绘制
             0.0f,  0.622008459f, 0.0f,   // 顶
            -0.5f, -0.311004243f, 0.0f,   // 左底
             0.5f, -0.311004243f, 0.0f    // 右底
        };
    
        // 设置图形的RGB值和透明度
        float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
    
        public Triangle() {
            // 初始化顶点字节缓冲区,用于存放形状的坐标,
            ByteBuffer bb = ByteBuffer.allocateDirect(
                    // (每个浮点数占用4个字节)
                    triangleCoords.length * 4);
            // 设置使用设备硬件的原生字节序
            bb.order(ByteOrder.nativeOrder());
    
            // 从ByteBuffer中创建一个浮点缓冲区
            vertexBuffer = bb.asFloatBuffer();
            // 把坐标都添加到FloatBuffer中
            vertexBuffer.put(triangleCoords);
            // 设置buffer从第一个坐标开始读
            vertexBuffer.position(0);
        }
    }
    

            默认情况下,OpenGL ES 假定GLSurfaceView帧的中心是坐标系[0,0,0](X,Y,Z),[1,1,0]是右上角,[-1,-1,0]是左下角。有关这个坐标系统的说明,请参阅OpenGL ES开发人员指南。
            注意这个形状的坐标是按逆时针方向定义的。绘制顺序很重要,因为它定义了哪个面是形状的正面,哪个面是反面。使用OpenGL ES的cullface特性,你可以只画正面不画反面。更多关于faces和culling的信息,请参阅OpenGL ES开发人员指南。

    2定义一个正方形

            在OpenGL中定义三角形非常容易,如果想得到一个更为复杂的形状,比如说一个正方形,有很多方法可以做到,其中典型的做法是使用两个三角形集合而成。

            在此之后,需要分别为两个三角形按逆时针方向定义这些顶点,并且将这些坐标值都存放到一个ByteBuffer中。为了避免分别为两个三角形定义两个坐标数组,我们使用一个绘制列表来告诉OpenGL ES图形管道如果绘制这些顶点。下面就是这个形状的代码:
    class Square {
    
        private FloatBuffer vertexBuffer;
        private ShortBuffer drawListBuffer;
    
        // 设置每个顶点的坐标数
        static final int COORDS_PER_VERTEX = 3;
        static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // 左上
                                        -0.5f, -0.5f, 0.0f,   // 左下
                                         0.5f, -0.5f, 0.0f,   // 右下
                                         0.5f,  0.5f, 0.0f }; // 右上
    
        private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // 设置顶点的绘制顺序
    
        public Square() {
            // 初始化顶点字节缓冲区,用于存放形状的坐标
            ByteBuffer bb = ByteBuffer.allocateDirect(
                    // (每个浮点数占用4个字节)
                    squareCoords.length * 4);
            bb.order(ByteOrder.nativeOrder());
            vertexBuffer = bb.asFloatBuffer();
            vertexBuffer.put(squareCoords);
            vertexBuffer.position(0);
    
            // 初始化字节缓冲区,用于存放绘制列表
            ByteBuffer dlb = ByteBuffer.allocateDirect(
                    // (每个短整型占用2个字节
                    drawOrder.length * 2);
            dlb.order(ByteOrder.nativeOrder());
            drawListBuffer = dlb.asShortBuffer();
            drawListBuffer.put(drawOrder);
            drawListBuffer.position(0);
        }
    }
    

           这个例子展示了如何使用OpenGL创建更为复杂的形状。一般来说,都是通过绘制三角形对象集合的方式来达到。在下一节中,你将了解如何在屏幕上画出这些形状。

  • 相关阅读:
    数组的方法 Array.map();Array.every()和Array.some();数组的indexof();检测是否是数组isArray(obj);
    jsonp的三种跨域方式
    Python函数的参数
    Python 函数
    collection 类
    字符串,列表,元组,字典基本函数
    图像处理------图像加噪 分类: 视频图像处理 2015-07-24 09:26 24人阅读 评论(0) 收藏
    图像处理------理解卷积 分类: 视频图像处理 2015-07-24 09:25 24人阅读 评论(0) 收藏
    图像处理------颜色梯度变化 (Color Gradient) 分类: 视频图像处理 2015-07-24 09:23 27人阅读 评论(0) 收藏
    图像处理------噪声之美
  • 原文地址:https://www.cnblogs.com/innosight/p/3271164.html
Copyright © 2011-2022 走看看