Using OpenVG for 2D graphics in auto infotainment displays
OpenVG is an API designed for hardware-accelerated 2D vector graphics. It was designed to help manufacturers create more attractive user interfaces by offloading computationally intensive graphics processing from the CPU onto a GPU to save energy. It is being used across many platforms, including a number of embedded applications. In this article we will describe the basic capabilities of the OpenVG spec and how to use it in automotive infotainment and instrument display applications.
OpenVG handles two main parent objects:
Bitmap: a memory organization used to store/draw an image. Every x and y coordinate will have a corresponding pixel. Each pixel is assigned an alpha, red, green and blue (ARGB) value, thus a 200 x 200 resolution image will require (200*200*(color depth)) bytes of storage. Bitmaps are particularly useful for photorealistic graphics. The coverflow application depicted in the Use Cases section contains image handling code and functions.
Vector: a mathematical formula that requires start and end points. Depending on how those points are connected, other parameters may be required, such as curve control points, arc radiuses, and arc angles. This feature makes a vector fully scalable, as it does not rely on per-pixel data to represent an image.
Figure 1 depicts how both circles appear to be the same when viewed at a normal size, but when zooming in, the bitmap image begins to lose fidelity, while the edge remains sharp in the vector image.
Vectors do not hold an advantage over bitmaps in all scenarios. Though bitmaps appear sharp at a fixed size, they become pixilated when scaled. Bitmaps are also faster to process but require more memory. Vectors maintain their image quality at any scale/size and occupy less memory. Vector images can only come from vector design tools, while bitmaps can be a photograph, or an image from any source or pixel-based tool.
Advantages of OpenVG
OpenGL can accomplish many graphical tasks, such as fonts, 2D GUIs and HMI. However, its strength lies in polygon and texture pushing power. OpenGL is bitmap oriented, and simple graphics can take precious time from that powerful OpenGL core.
OpenVG closes the gap on graphical needs. On its own, it can provide for great applications, and in combination with OpenGL, it can manage fonts, vectors, and most 2D and pseudo 3D elements, while an OpenGL core dedicates its time to doing what it does best.
When used stand-alone, OpenVG can accomplish a lot with low current and memory consumption. When combined with OpenGL, OpenVG manages the tasks the OpenGL core was not designed to perform.
Raster images (bitmaps)
Handling images in OpenVG is straightforward. Follow these steps to draw an image on your rendering surface:
- Declare a VGImage object.
- Create a VGImage and assign the handler to your VGImage object.
- Fill the image with the bitmap data.
- Set the matrix mode to VG_MATRIX_IMAGE_USER_TO_SURFACE in order to transform images (3 x 3 afine transformations).
- Draw your image.
Apply the same steps in pseudo code:
ovgarticle_image = vgCreateImage(VGImageFormat format, VGint width, VGint height, VGbitfield allowedQuality)
vgImageSubData(VGImage image, const void * data, VGint dataStride, VGImageFormat dataFormat, VGint x, VGint y, VGint width, VGint height)
To perform this operation, you must be familiar with certain bitmap aspects, such as stride, bit depth, and set API properties such as blending.
Paths form the core of vector-accelerated graphics. To fully grasp this concept, you must understand the following:
- Path: Series of points that are bounded by segments.
- Point: Coordinate value.
- Segment: Type of union between two points. It may consume more points that act as control values for the segment.
A simple triangle path can serve as an example. First, you must define the segments that will integrate the whole path. The segments of a path are described as a series of commands stored in an array of bytes. Each command (Table 1) will consume one or more points.
Complex paths involve the use of arcs and bezier curves.
The steps to create and draw a path in OpenVG include:
- Declare a VGPath object.
- Declare a segment and point array
- Create an empty path that will accept segment data (vgCreatePath).
- Fill segment and point data to the path (vgAppendPathData).
- Draw the path (vgDrawPath).