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创建更为复杂的形状。一般来说,都是通过绘制三角形对象集合的方式来达到。在下一节中,你将了解如何在屏幕上画出这些形状。

  • 相关阅读:
    HDU 2852 KiKi's K-Number (主席树)
    HDU 2089 不要62
    Light oj 1140 How Many Zeroes?
    Bless You Autocorrect!
    HDU 6201 transaction transaction transaction
    HDU1561 The more ,The better (树形背包Dp)
    CodeForces 607B zuma
    POJ 1651 Mulitiplication Puzzle
    CSUOJ 1952 合并石子
    Uva 1599 Ideal path
  • 原文地址:https://www.cnblogs.com/innosight/p/3271164.html
Copyright © 2011-2022 走看看