World Wide Guide | Knowledge BankKukushkin's Notebook | Design Fundamentals


Drawing primitives

In computer graphics, a primitive is a graphics element that is used as a building block for creating images, such as a point, line, arc, cone or sphere.

Reference points and
the delta coordinate system

In FS5, projecting real-world coordinates of each graphics primitive onto the screen would take an immense amount of processing time. For this reason, the graphics engine of the program works in a so-called delta coordinate system instead.

Before the drawing can begin, the SDL code must define a so-called reference point (RefPoint) using real-world coordinates (lat/lon/alt). The graphics engine determines the relative position of the RefPoint to the View window and establishes a (Cartesian) coordinate system around the RefPoint. This is the delta coordinate system. Drawing instructions themselves never use real-world coordinates, but work in the delta coordinate system instead.

Besides its geographical location, a RefPoint also has a so-called scale factor. This scale factor determines the length of the unit for the delta coordinate system, in meters. With very few exceptions, delta coordinates are specified as 16-bit signed integer numbers. This limits their range to between -32,767 and 32,767, and also prohibits fractional values. Some scenery compilers allow entering fractional parts for delta coordinates or even calculate them automatically from real-world coordinates. However, it must be clearly understood that fractional parts of delta coordinates can never make it into the BGL file, because its format has no place for them. Thus, the precision of coordinates in the BGL file is limited by the scale factor of the RefPoint.

This does not mean the less the scale factor the better, because the visibility range of a RefPoint decreases with decreasing scale factor. More on this can be found in How to stay within limits.

Two kinds of drawing instructions

There are two families of drawing instructions. Some instructions require points defined using Points()/VecPoints() instructions [or in FSASM, DefPoints/DefVecPoints], while a few others allow specifying coordinates directly. Most polygon drawing instructions require defining points.

Some primitives are drawn using multiple instructions. For example, a line segment is drawn by first setting its beginning using MoveTo[Pt]() and then setting its end using DrawTo[Pt]() [FSASM: LineTo/DrawToPt]. In such cases, it is important not to mix instructions that use pre-defined points and directly specified coordinates. For instance, the sequence

MoveToPt( 0 ) DrawTo( 1000 0 1000 )

would draw the line incorrectly. The line could be drawn correctly either by using MoveTo() instead of MoveToPt() or by using DrawToPt() instead of DrawTo().

The choice between using points and explicit coordinates should be made in order to reduce the resulting code size. Also, explicit coordinates should not be used in ShadowCalled objects.

When FS5 draws a polygon, it projects coordinates of its vertices onto the screen and then instructs the graphics driver to draw a 2-D polygon. FS5 does not check whether all vertices are located in one plane. This must be ensured by the scenery designer.

Instructions that are expected to draw concave polygons should be prefixed by the ConcavePoly() instruction. 'Concave' here means that at least one inner angle of the polygon exceeds 180 degrees. The surface of the polygon is flat and never concave!

Introducing vectors

Vectors in FS5 are used for defining directions and imaginary planes. Even in polygon drawing instructions, where it would theoretically be possible to derive the plane equation from polygon vertices, FS5 requires defining the polygon plane using a vector and uses this plane for its visibility tests and shading.

Directions are defined simply by specifying 3 components of a vector. A plane is defined by specifying the coefficients of its equation: ax+by+cz+d=0. a,b,c are also components of a vector orthogonal to this plane. In some polygon drawing instructions, the coordinates of some point on the plane are specified instead of the 'd' parameter.

Visibility tests done by VectorJump() and many polygon drawing instructions check if the viewpoint is "above" the plane of the polygon. This is done by calculating ax+by+cz+d, where x,y,z are delta coordinates of the viewpoint. If the result is a positive number, the viewpoint is "above" the plane.

Compilers offer automatic vector calculation

Most scenery compilers have an 'automatic' vector mode. In this mode, they calculate plane equations and the like from coordinates of points specified for a polygon, instead of forcing the user to do such calculations. Because such calculations are done at compile time, they are only affected by the order of instructions in the source file. They are NOT affected by the actual execution order:

If...( :Shape2_points ... ) ; Choose between two shapes for the polygon
:Shape1_points
Points( ... ) ; Points for shape 1 Jump( :Draw_it )
:Shape2_points
Points( ... ) ; Points for shape 2
:Draw_it      ; Use a single Poly() instructions for both shapes
Poly( a ... ) ; The auto-vector is always calculated for shape 2

Because the assembler processes Points() for shape 2 after Points() for shape 1, the vector for Poly() [FSASM: FlatPoly] is always calculated in the assumption that the polygon is drawn using shape 2 points. This can lead to problems with shape 1 when the two shapes lie in different planes.

Similarly, if a subroutine is used to define points, the assembler does not know about them when it processes the polygon drawing instruction. Instead, point coordinates specified in the last Points() instruction PROCESSED BY THE ASSEMBLER would be used. In most cases, this would cause the assembler to insert a wrong vector into the output file:

Call( :Define_points ) ; Define points
Poly( a ... )          ; Draw a polygon using these points... or not?
...
:Define_points
Points( ... )
Return

As it translates the Poly() instruction, the assembler does not yet know about points defined in the subroutine. This would either produce an error or result in the visibility vector calculated for wrong points.

A more detailed description of vectors can be found in FS5STRUC.TXT by Maurizio Gavioli.


Last updated 11 October 1996 by Gene Kraybill.