【Android Developers Training】 63. 定义形状

系统 1885 0

注:本文翻译自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创建复杂图形的启发,通常来说,你需要使用三角形的集合来绘制对象。在下一节课中,你将学习如何在屏幕上画这些形状。

【Android Developers Training】 63. 定义形状


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论