Graphics Standards and Primitives
A person who wants to develop a graphics program has to learn how to access the graphics capabilities of the system that he/she is working on. Unfortunately, there are many graphics devices out there in the world. If one wanted a program to work with all those devices and if one had to program the hardware directly, then one could easily spend all of one’s time on very low-level code and never get to that in which one is really interested. Therefore, let somebody else, say the manufacturer of the system or the compiler vendor, worry about the low-level stuff so that one can concentrate on higher-level ideas. This is where software graphics standards come in. They are the interface between a high-level language and the low-level code that talks to the actual hardware. The interface is basically a specification of high-level graphics primitives. As long as one’s code calls only these primitives, a program will run on any system that is supported by that particular interface. In other words, standards make code portable by making it device independent.
Lots of different standards exist with some more sophisticated than others. The early DOS operating system standards, such as the Borland Graphics Interface (BGI), were fairly primitive. Any program in Borland PASCAL or C/C++ that used the Borland PASCAL or C/C++ graphics primitives was guaranteed to run under DOS on most of the IBM PC-compatible computers. The same was true of the corresponding interface found in the Microsoft compilers. A number of much more sophisticated standards were developed over the years such as
Core (The 3d Core Graphics System): specified by ACM SIGGRAPH committees in 1977 and 1979 ([GSPC77] and [GSPC79])
GKS (Graphics Kernel System): specified by various national and international committees in the 1980′s with a 3d version becoming a standard in 1988 ([ANSI85], [ISO 88], [EnKP84], [BDDH95])
PHIGS (Programmer’s Hierarchical Interactive Graphics System): a more complex standard than GKS, which was specified by ANSI (the American National Standards Institute) in 1988 ([ANSI88] and [VanD88])
See [Cars98] for a brief history. Two more recent standards are
OpenGL: see [WNDS99], [KemF97], [WriS00]
DirectX: see [Glid97], [BarD98], [Timm96]
The rise in the popularity of the Microsoft Windows operating system meant that its application programming interface (API) became a driving force for standards for that system. At first there was only the basic Windows graphics device interface (GDI). This made writing graphics programs hardware independent, but at the expense of speed. The result was that developers, especially those involved in writing games, stayed with DOS, which allowed programmer to go directly to the hardware and squeeze out the last ounce of speed essential for games. To attract developers to Windows, Microsoft next came out with WinG, which provided a few low-level bitmap functions that did speed up basic graphics operations substantially, but it was not enough. Microsoft’s graphics standard successors to WinG were DirectDraw and Direct3D, which were part of the DirectX API that was intended for multimedia applications. DirectDraw provided two-dimensional graphics primitives. Direct3D was the three-dimensional counterpart. Although these allowed for high-performance graphics under Windows, DirectDraw and Direct3D were low level. A competing and higher-level graphics API is OpenGL, a graphics standard originally developed by Silicon Graphics, Inc., for its graphics workstations. Good implementations of OpenGL for Windows are built on DirectX drivers. Although native DirectX code is currently faster, the advantage of OpenGL is that it is available on many other computer and operating system platforms, a plus for Internet applications. The companion programs for this topic, GM and SPACE, use OpenGL.
Having just praised standards, we also need to point out what has traditionally been their downside. If one uses a standard, then one must be willing to put up with extra overhead in the code. Furthermore, because standards are device independent, they, by definition, usually do not take advantage of any special features that a particular piece of hardware may have. What this means is that programs that use them are sometimes much slower on a particular machine than a program that accesses its hardware features directly. Software developers have often been forced to choose between device independence and speed in those cases where speed is critical. Fortunately, with DirectX and OpenGL the situation has much improved and this is no longer a serious problem.
From Window to Viewport
One of the first bits of mathematics one runs into in a graphics program is the transformation from the window to the viewport. Both the window and viewport are representable as rectangles in the plane whose sides are parallel to the coordinate axes. What we are looking for is a simple map from one of these rectangles to another. Intuitively, all this amounts to is a change of scale.
The standard representation for our rectangles is as products of intervals in the form [a,b] x [c,d]. Normally, the implied assumption in the representation of an interval like [a,b] is that a < b; however, in our current context where we will be interested in maps from one interval to another, we do not require that. It will be useful to allow a > b. Returning to our discussion of windows and viewport, if one uses normalized device coordinates, the viewport is a subrectangle of [0,1] x [0,1]. If one considers the viewport as a rectangle in the raster, then it has the form [mi,m2] x [ni,n2], where mj and n are integers. There is one caveat, however. The (0,0) position in the raster has traditionally been associated to the top left-hand corner on the screen. That means that the y-axis has to be inverted because users always think of that axis as going up, not down. In other words, if, say, the resolution is 800 x 600 and the viewport is the entire screen, then the viewport should be represented by the rectangle [0,799] x [599,0].
Mathematically then, the search for the window-to-viewport transformation boils down to the following: Ifare the rectangles that represent the window W and viewport V, respectively, then we want a map ‘of the form
where each Ti is linear. In other words, we have two one-dimensional problems of the form:
The second form of the answer says that we send x to that point in [c,d], which is the same percentage of the way from c to d as x is from a to b. If one remembers that intuitive fact then one has no need to solve equations because the answer is obvious. At any rate, we now have the following solution for T: