Tagged: 2D Rendering Toggle Comment Threads | 键盘快捷键

  • Roger 3:01 pm on May 15, 2011 固定链接 | 回复
    Tags: , 2D Rendering, ,   

    Google I/O 2011, Android Accelerated Rendering 

    Google I/O上关于的Android 3.0 Honeycomb 硬件加速绘图的介绍:

    PPT:http://www.slideshare.net/romainguy/google-io-2011-android-accelerated-rendering

    YouTube:http://www.youtube.com/watch?v=v9S5EO7CLjo

    主要内容介绍(因为没有字幕,部分听不清楚的地方只能靠自己的猜测,可能有错误的地方):

    1. 在Honeycomb之前,使用到GPU的地方包括OpenGL(直接使用NDK或者Java的Wrapper),Live Wallpaper(内部使用Render Script,其实也是间接使用OpenGL,但是相关API直到Honeycomb才开放),Window Compositing(窗口混合,也就说把多个窗口的Surface进行Alpha混合输出到屏幕的Surface上面);但是最常见的UI组件的绘制,使用的2D绘图引擎Skia是没有使用GPU加速的。
    2. 在Honeycomb上面,UI组件的绘制,也就是Canvas API,使用了OpenGLRenderer作为Backend,从而利用GPU进行加速。(在这里不太清楚是Skia内部支持OpenGL作为Backend,还是使用新的2D绘图引擎取代Skia,个人猜测应该是前者)
    3. 因为OpenGL实际上只支持多边形绘制和贴图,所以利用OpenGL做2D绘图,实际上是在内部生成一个多边形构成的平面,然后把背景图,前景图,线段,文字生成的位图贴在上面。
    4. 要使App支持硬件加速,需要在Mainifest中进行设置,可以分别对App,Activity,Window,View这几个级别单独进行设置,不过不支持在关闭整个Window硬件加速的情况下开启其中的View的硬件加速,只支持相反的情况,可以在开启整个Window硬件加速的情况下关闭其中部分View的硬件加速。View和Canvas支持运行时查询是否支持硬件加速。
    5. 不是所有的Canvas API都支持硬件加速,部分比较不常用的API是没有硬件加速支持的。
    6. 新的UI组件渲染模型引入了DisplayList来减少一个View被invalidate时所需要的重绘操作。
    7. 使用Layer(内部位图缓存)可以加速部分绘图操作,当这些绘图不是因为本身的内容更新引起的,而是因为View被移动,旋转,透明度改变或者加入特效等引起的(也就说View本身的DisplayList没有被改变,而是View的Parent的DisplayList被改变)。
    8. 如果是Hardware Layer,它实际是分配在显存的Texture,GPU重绘一个Texture的速度非常的快,但是Layer的使用可能造成内存的过度使用和在View本身更新的情况下反而绘制较慢(等于先绘制到缓存然后再拷贝缓存),演示了一个例子当对一个View进行动画时才开启Layer,动画结束后关闭。
    9. Tips and Tricks:
      • 减少View的层次,尽量使组件树扁平化
      • setAlpha操作的成本很高
      • 尽量重用Paint,Bitmap对象
      • 不要频繁改变Bitmap对象
      • 不要频繁改变Path对象
      • 避免不必要的绘制
      • 使用DDMS和Traceview做Profiling
     
  • Roger 7:00 pm on April 20, 2011 固定链接 | 回复
    Tags: , 2D Rendering,   

    Java 2D Graphics Reading Notes [3] 

    第三章 Geometry 几何图形

     

    这一章主要讲述的内容

    • 表示点的类
    • 两个用于描述几何图形的重要接口:Shape和PathIterator
    • java.awt.geom包里面各种表示不同几何图形的类
    • 多个图形组合后的新图形

     

    点(Points)

     

    在Java 2D中,几何图形都有类似的类阶层模式,一个抽象类代表一个二维平面的一个几何图形,它的若干内部类派生自这个抽象类,分别提供不同的坐标精度(整数,单精度浮点数,双精度浮点数)。

     

    image

    代表一个2D平面上的点的类阶层结构

     

    图形和路径(Shapes and Paths)

     

    回顾第二章的内容,Java 2D的图形渲染引擎Graphics2D的两种最基本的操作是图形填充和图形轮廓的绘制,对于Graphics2D而言,所有图形都是一个Shape(java.awt.Shape),一个Shape可能包括轮廓和内部区域,Graphics2D的draw方法用于绘制Shape的轮廓,fill方法用于填充Shape的内部区域。

     

    Shape的getBounds和getBounds2D方法可以返回一个矩形,它是图形的外廓矩形,刚好能够包裹Shape。

     

    image

    不同Shape的Bounds

     

    Shape还有一系统方法用于判断包括,相交等状况,不过它最重要的方法还是getPathIterator,用于返回一个描述图形轮廓的路径(PathIterator)。

     

    image

    Java 2D 内置提供的所有的Shape

     

    Shape的边界被称为路径(Path)。路径是由一系列基本指令组成,用于从一个点移动到另外一个点。比如下面的指令描述了一个正方形的轮廓。

    1. 移动到0,0
    2. 画一条线到72,0
    3. 画一条线到72,72
    4. 画一条线到0,72
    5. 画一条线回0,0

     

    在Java 2D中,PathIterator封装了一个路径的全部片段(segments),用来描述图形的轮廓。Shape的getPathIterator方法用来返回该Shape的PathIterator,PathIterator跟Enumeration类似,程序可以从开始逐个访问每一个片段直到路径的结束。

     

    Java 2D定义了5种可能的片段类型:

    1. SEG_MOVETO 用于移动当前的位置,不进行任何绘制操作
    2. SEG_LINETO 绘制一条直线
    3. SEG_QUADTO 绘制二次曲线
    4. SEG_CUBICTO 绘制三次曲线
    5. SEG_CLOSE 绘制一条直线回最后SEG_MOVETO的位置,用于结束当前的子路径

     

    image

    二次曲线包含一个控制点

     

     

    image

    三次曲线包含两个控制点

     

    PathIterator的currentSegment方法可以用来查询当前的路径片段,next方法可以用来移动到下一个片段,isDone用于查询是否到了路径的终点。

     

    image

    用于打印一个图形的轮廓路径的示例代码

     

    如果图形是一个比较复杂的轮廓路径相互缠绕的图形,如何对重叠区域进行判断是否属于图形的内部区域,Java 2D定义了两种缠绕规则(winding rules),WIND_EVEN_ODD和WIND_NON_ZERO用于图形内部区域的判断。PathIterator的getWindingRule方法可以用于返回该路径使用的缠绕规则。

     

    image

    WIND_EVEN_ODD规则

     

    WIND_EVEN_ODD规则定义了:画一条直线穿越整个图形,每次跟图形的边界相交,则计数器加1(从1开始计数),当交点的计数器是奇数的时候,以它为起点到下一个交点的线段处于图形的内部。

     

    image

    WIND_NON_ZERO规则

     

    WIND_NON_ZERO规则定义了:画一条直线穿越整个图形,每次跟图形的边界相交时,如果相交的边是从左向右的,则计数器加1(从0开始计数),如果相交的边是从右向左的,则计数器减1。当交点的计数器为0时,以它为起点到下一个交点的线段处于图形的内部。在这种规则下,图形反过来画,结果也是一样的。

     

    Java 2D除了提供一系列内置的图形外,GeneralPath可以用于产生自定义的图形的轮廓(GeneralPath派生自Shape)。

     

    image

    通过程序创建一个自定义图形的示例代码

     

    直线和曲线(Lines and Curves)

     

    Java 2D里面已经包括了一组表示直线和曲线的类,并且都实现了Shape接口,虽然程序可以使用GeneralPath来创建,不过直接使用现成的类会更方便。

     

    image

    Line2D的类阶层

     

    QuardCurve2D和CubicCurve2D可以用来构造二次曲线和三次曲线。

     

    矩状图形(Rectangles)

     

    RectangularShape是一个抽象类,用来表示那些被矩形包裹的图形,包括矩形,圆角矩形,椭圆形,弧形等。

     

    image

    圆角矩形

     

     

    image

    弧形

     

    构造性区域图形(Constructive Area Geomerey)

     

    在Java 2D中,我们可以把多个图形用不同的方式组合形成一个新的图形,新的图形类型为Area,它用来表示多个图形的组合。

     

    image

    不同的图形组合方式

     
  • Roger 7:04 pm on April 10, 2011 固定链接 | 回复
    Tags: , 2D Rendering,   

    Java 2D Graphics Reading Notes [2] 

    渲染引擎(Rendering Engine)

    所谓渲染是这样一个过程,它处理一组图形,文本和图像的集合,然后计算出在屏幕或者打印机上的像素应该是什么颜色。图形,文本和图像被称为图元(graphics primitives),屏幕和打印机被称为输出设备(output devices),而负责处理这一绘制过程的就是所谓的渲染引擎,在Java 2D API中,其中的2D渲染引擎就是类Graphics2D,Graphics2D同时还表示一个绘制表层(drawing surface),该绘制表层可以是窗口的表面,可以是打印中的页面,还可以是离屏位图。

     

    image

    渲染引擎把图元绘制到输出设备上

     

    渲染流水线(Rendering Pipeline)

    渲染引擎的状态

    渲染引擎使用内部的状态来决定如何将图元转换成像素颜色,Graphics2D的内部状态一共包括7种元素:

    1. paint 笔刷决定了图形如何填充
    2. stroke 笔画决定了图形的轮廓如何绘制
    3. font 字体决定了文本中的字符生成的图形的形状
    4. transformation 所有的图元在真正渲染前都会先执行几何变换
    5. composting rule 混合规则决定当前绘制的图元的颜色如何跟绘制表层的现有颜色进行混合
    6. clipping shape 裁剪区域决定了有效的绘制区域,如果为空,则整个绘制表层都可以被绘制
    7. rendering hints 渲染示意决定了渲染过程中的可能采用的不同演算法
      所谓渲染流水线就是渲染引擎处理图元绘制的一系列过程,下图显示了Graphics2D内部的7种状态如何影响渲染过程:

      image

      渲染流水线

      在Java 2D API中:

      • fill()方法用于图形的填充
      • draw()方法用于图形轮廓的绘制
      • drawString()方法用于绘制文本
      • drawImage()方法用于绘制图像

      整个绘制过程可分为5步,第一步主要取决于要绘制的图元:

      1. 对于绘制图形轮廓或者绘制文本,实际上都是生成一个轮廓的图形或者文本的图形,然后对生成的图形进行填充,所以实际上只有两种最基本的绘制,图形填充和图像绘制。而第一步就是对图形或者图像进行几何变换;
      2. 对图形进行光栅化,根据图形生成一个像素覆盖值(pixel coverage values)集合,值的大小由该像素跟图形区域的相交状况决定,光栅化的算法通常由渲染示意决定;
      3. 使用裁剪区域设置进行裁剪;
      4. 根据当前的笔刷设置进行图形填充(图像则直接跳过这一步);
      5. 跟绘制表层已有的颜色进行混合,最后输出混合后的颜色;

        Alpha, Alpha, Alpha!!!

        渲染是一个近似的过程。当你希望填充一个理想的图形时,实际上渲染引擎只能试图计算出输出设备的像素应该如何着色来得到一个最逼近绘制图形的结果。举例来说,假设程序要用纯色填充一个图形,有快速但是绘制质量不高的算法,也有绘制质量高但是速度较慢的算法。

        锯齿和反锯齿

        快速的算法就是只填充完全位于图形之内的像素。下图的R则采用了这种算法进行填充:

        image

        狗齿遍布的R

        好的算法则根据像素跟图形交叠的区域计算出一组像素覆盖值,然后以覆盖值作为比例系数来对像素进行着色,这种技术被称为反锯齿。

        image

        经过反锯齿算法渲染的R有着更平滑的边缘

        光栅器(Rasterizer)

        在渲染流水线中,光栅器负责将理想的图形转换成一组像素覆盖值,也就是所谓的alpha值,图像所有alpha值的集合被称为alpha通道。

        像素的alpha值决定了它的透明度,如果把alpha值看作是颜色的一部分,它就是颜色的透明程度。Alpha值位于0.0~1.0之间,0.0代表像素跟图形完全不交叠,1.0则代表像素完全位于图形之内,而反锯齿算法则为部分交叠的像素产生一个0.0~1.0之间的值。

        image

        光栅器使用反锯齿算法产生的alpha值

        然而最终像素的颜色的决定还不仅仅取决于绘制的图形,它还取决于如何跟原有的像素颜色进行混合。

         

        混合(Compositing)

        当光栅器为绘制的图形产生alpha值后,混合规则决定了待绘制的颜色如何跟绘制表层原有的颜色进行混合产生最终的输出颜色,混合规则其实就是一个方程式对每个像素进行计算,最简单的算法就是待绘制的颜色完全取代原有的颜色。

        image

        绘制新的图形到绘制表层

         

        坐标空间(Coordinate Space)

        Java 2D的图形被绘制一个笛卡尔坐标平面上,这个平面被称为所谓的用户空间(User Space)。当实际输出到显示器或者打印机时,用户空间坐标需要被转换成设备空间(Device Space)坐标,通常情况下,设备空间以1像素为1单位。一般而言,用户空间和设备空间是对齐的,默认情况下72个用户空间单位为1英寸,而显示器的DPI值默认刚好是72DPI。也就是说当输出设备是显示器,并且在默认设置下时,1用户空间单位刚好是1像素,并且用户空间到设备空间的转换比例刚好是1:1。(书中的最后一段比较难理解,只能是看到后面的章节再重新回顾这一段…)

         
      1. Roger 3:12 pm on April 10, 2011 固定链接 | 回复
        Tags: , 2D Rendering,   

        Java 2D Graphics Reading Notes [1] 

        image

        Java 2D Demo

        Java 2D Graphics

        Java 2D Graphics是一本介绍Java 2D API的书,但是它可贵之处在于并不仅仅告诉你这些API的用法,而是透过Java 2D API的使用讲解2D绘图的基本原理和概念,甚至包括Java 2D API内部的一些实现细节。通过这本书,不但可以学习到Java 2D API的使用方法,还能学习到很多关于2D绘图和2D绘图引擎实现的知识,从而使得要掌握其它GUI工具库的2D绘图引擎的使用也变得十分简单,甚至还可以自己实现一个完整2D绘图引擎或者其中部分的功能。

        一个2D绘图引擎可以做什么

        1. shapes 图形,可以创建由直线或者曲线组成的任意形状的图形
        2. stroking 笔画,可以使用不同的笔画绘制线段和图形的轮廓
        3. filling 填充,可以使用纯色,图案,渐变色等各种方式来填充一个图形
        4. transfromation 几何变换,可以对绘制的图元进行拉伸,挤压,旋转等几何变换
        5. alpha compositing alpha混合,可以支持多种alpha混合算法
        6. clipping 裁剪,可以对绘制设置任意形状的裁剪区域
        7. antialiasing 反锯齿,可以使用反锯齿技术避免参差不齐的边缘
        8. text 文本绘制,支持TureType和Type 1字体加载,根据加载的字体生成字符的图形,然后进行绘制
        9. color 颜色校正,支持对颜色进行校正,符合设备的特性和当前的照明条件
        10. images 图像,支持图像的绘制,包括几何变换,裁剪,alpha混合,还支持不同图像格式的编码和解码
        11. image processing 图像处理,可以对图像做简单的特效处理
        12. printing 打印,支持绘制到打印机
         
      c
      Compose new post
      j
      Next post/Next comment
      k
      Previous post/Previous comment
      r
      回复
      e
      编辑
      o
      Show/Hide comments
      t
      返回顶部
      l
      Go to login
      h
      Show/Hide help
      shift + esc
      取消