1The Open Scene Graph library, which current FlightGear uses for its 3D
2graphics, provides excellent support for multiple views of a
3scene. FlightGear uses the osgViewer::Viewer class, which implements a
4"master" camera with "slave" cameras that are offset from the master's
5position and orientation. FlightGear provides the "camera group"
6abstraction which allows the configuration of slave cameras via the
7property tree.
8
9Slave cameras can be mapped to windows that are open on different
10screens, or all in one window, or a combination of those two schemes,
11according to the video hardware capabilities of a machine. It is not
12advisable to open more than one window on a single graphics card due
13to the added cost of OpenGL context switching between the
14windows. Usually, multiple monitors attached to a single graphics card
15are mapped to different pieces of the same desktop, so a window can be
16opened that spans all the monitors. This is implemented by Nvidia's
17TwinView technology and the Matrox TripleHead2Go hardware.
18
19The camera group is configured by the /sim/rendering/camera-group node
20in the property tree. It can be set up by, among other things, XML in
21preferences.xml or in an XML file specified on the command line with
22the --config option.
23
24Here are the XML tags for defining camera groups.
25
26camera-group
27For the moment there can be only one camera group. It can contain
28window, camera, or gui tags.
29
30 window
31 A window defines a graphics window. It can be at the camera-group
32 level or defined within a camera. The window contains these tags:
33
34  name - string
35  The name of the window which might be displayed in the window's
36  title bar. It is also used to refer to a previously defined
37  window. A window can contain just a name node, in which case
38  the whole window definition refers to a previously defined window.
39
40  host-name - string
41  The name of the host on which the window is opened. Usually this is
42  empty.
43
44  display - int
45  The display number on which the window is opened.
46
47  screen - int
48  The screen number on which the window is opened.
49
50  x, y - int
51  The location on the screen at which the window is opened. This is in
52  the window system coordinates, which usually puts 0,0 at the upper
53  left of the screen XXX check this for Windows.
54
55  width, height - int
56  The dimensions of the window.
57
58  decoration - bool
59  Whether the window manager should decorate the window.
60
61  fullscreen - bool
62  Shorthand for a window that occupies the entire screen with no
63  decoration.
64
65  overrideRedirect - bool
66  Only effective when fullscreen = true.
67  Provides an extra hint for Gnome-based linux systems that we insist that
68  the full screen window span *all* physical displays, not just the current
69  physical display.
70
71 camera
72 The camera node contains viewing parameters.
73
74  window
75  This specifies the window which displays the camera. Either it
76  contains just a name that refers to a previous window definition, or
77  it is a full window definition.
78
79  viewport
80  The viewport positions a camera within a window. It is most useful
81  when several cameras share a window.
82
83   x, y - int
84   The position of the lower left corner of the viewport, in y-up
85   coordinates.
86
87   width, height - int
88   The dimensions of the viewport
89
90  view
91  The view node specifies the origin and direction of the camera in
92  relation to the whole camera group. The coordinate system is +y up,
93  -z forward in the direction of the camera group view. This is the
94  same as the OpenGL viewing coordinates.
95
96   x,y,z - double
97   Coordinates of the view origin.
98
99   heading-deg, pitch-deg, roll-deg - double
100   Orientation of the view in degrees. These are specified using the
101   right-hand rule, so a positive heading turns the view to the left,
102   a positive roll rolls the view to the left.
103
104  perspective
105  This node is one way of specifying the viewing volume camera
106  parameters. It corresponds to the OpenGL gluPerspective function.
107
108   fovy-deg - double
109   The vertical field-of-view
110
111   aspect-ratio - double
112   Aspect ratio of camera rectangle (not the ratio between the
113   vertical and horizontal fields of view).
114
115   near, far - double
116   The near and far planes, in meters from the camera eye point. Note
117   that FlightGear assumes that the far plane is far away, currently
118   120km. The far plane specified here will be respected, but the sky
119   and other background elements may not be drawn if the view plane is
120   closer than 120km.
121
122   offset-x, offset-y - double
123   Offsets of the viewing volume specified by the other parameters in
124   the near plane, in meters.
125
126  frustum
127  This specifies the perspective viewing volume using values for the near
128  and far planes and coordinates of the viewing rectangle in the near
129  plane.
130
131   left, bottom - double
132   right, top - double
133   The coordinates of the viewing rectangle.
134
135   near, far - double
136   The near and far planes, in meters from the camera eye point.
137
138  ortho
139  This specifies an orthographic view. The parameters are the sames as
140  the frustum node's.
141
142 gui
143 This is a special camera node that displays the 2D GUI.
144
145  viewport
146  This specifies the position and dimensions of the GUI within a
147  window, *however* at the moment the origin must be at 0,0.
148
149Here's an example that uses a single window mapped across 3
150displays. The displays are in a video wall configuration in a
151horizontal row.
152
153<PropertyList>
154  <sim>
155    <rendering>
156      <camera-group>
157        <window>
158          <name>wide</name>
159          <host-name type="string"></host-name>
160          <display>0</display>
161          <screen>0</screen>
162          <width>3840</width>
163          <height>1024</height>
164          <decoration type = "bool">false</decoration>
165        </window>
166        <camera>
167          <window>
168            <name>wide</name>
169          </window>
170          <viewport>
171            <x>0</x>
172            <y>0</y>
173            <width>1280</width>
174            <height>1024</height>
175          </viewport>
176          <view>
177            <heading-deg type = "double">0</heading-deg>
178          </view>
179          <frustum>
180            <top>0.133</top>
181            <bottom>-0.133</bottom>
182            <left>-.5004</left>
183            <right>-.1668</right>
184            <near>0.4</near>
185            <far>120000.0</far>
186          </frustum>
187        </camera>
188        <camera>
189          <window>
190            <name type="string">wide</name>
191          </window>
192          <viewport>
193            <x>1280</x>
194            <y>0</y>
195            <width>1280</width>
196            <height>1024</height>
197          </viewport>
198          <view>
199            <heading-deg type = "double">0</heading-deg>
200          </view>
201          <frustum>
202            <top>0.133</top>
203            <bottom>-0.133</bottom>
204            <left>-.1668</left>
205            <right>.1668</right>
206            <near>0.4</near>
207            <far>120000.0</far>
208          </frustum>
209        </camera>
210        <camera>
211          <window>
212            <name>wide</name>
213          </window>
214          <viewport>
215            <x>2560</x>
216            <y>0</y>
217            <width>1280</width>
218            <height>1024</height>
219          </viewport>
220          <view>
221            <heading-deg type = "double">0</heading-deg>
222          </view>
223          <frustum>
224            <top>0.133</top>
225            <bottom>-0.133</bottom>
226            <left>.1668</left>
227            <right>.5004</right>
228            <near>0.4</near>
229            <far>120000.0</far>
230          </frustum>
231        </camera>
232        <gui>
233          <window>
234            <name type="string">wide</name>
235          </window>
236        </gui>
237      </camera-group>
238    </rendering>
239  </sim>
240</PropertyList>
241
242Here's a complete example that uses a seperate window on each
243display. The displays are arranged in a shallow arc with the left and
244right displays at a 45.3 degree angle to the center display because,
245at the assumed screen dimensions, the horizontal field of view of one
246display is 45.3 degrees. Each camera has its own window definition;
247the center window is given the name "main" so that the GUI definition
248can refer to it.  Note that the borders of the displays are not
249accounted for.
250
251<PropertyList>
252  <sim>
253    <rendering>
254      <camera-group>
255        <camera>
256          <window>
257            <host-name type="string"></host-name>
258            <display>0</display>
259            <screen>0</screen>
260            <fullscreen type = "bool">true</fullscreen>
261          </window>
262          <view>
263            <heading-deg type = "double">45.3</heading-deg>
264          </view>
265          <frustum>
266            <top>0.133</top>
267            <bottom>-0.133</bottom>
268            <left>-.1668</left>
269            <right>.1668</right>
270            <near>0.4</near>
271            <far>120000.0</far>
272          </frustum>
273        </camera>
274        <camera>
275          <window>
276            <name type="string">main</name>
277            <host-name type="string"></host-name>
278            <display>0</display>
279            <screen>1</screen>
280            <fullscreen type = "bool">true</fullscreen>
281          </window>
282          <view>
283            <heading-deg type = "double">0</heading-deg>
284          </view>
285          <frustum>
286            <top>0.133</top>
287            <bottom>-0.133</bottom>
288            <left>-.1668</left>
289            <right>.1668</right>
290            <near>0.4</near>
291            <far>120000.0</far>
292          </frustum>
293        </camera>
294        <camera>
295          <window>
296            <host-name type="string"></host-name>
297            <display>0</display>
298            <screen>2</screen>
299            <fullscreen type = "bool">true</fullscreen>
300          </window>
301          <view>
302            <heading-deg type = "double">-45.3</heading-deg>
303          </view>
304          <frustum>
305            <top>0.133</top>
306            <bottom>-0.133</bottom>
307            <left>-.1668</left>
308            <right>.1668</right>
309            <near>0.4</near>
310            <far>120000.0</far>
311          </frustum>
312        </camera>
313        <gui>
314          <window>
315            <name type="string">main</name>
316          </window>
317        </gui>
318      </camera-group>
319    </rendering>
320  </sim>
321</PropertyList>
322