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