]> git.mxchange.org Git - flightgear.git/blob - src/Viewer/WindowBuilder.cxx
considering u,v,wbody-fps are the ECEF velocity expressed in body axis, change in...
[flightgear.git] / src / Viewer / WindowBuilder.cxx
1 // Copyright (C) 2008  Tim Moore
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License as
5 // published by the Free Software Foundation; either version 2 of the
6 // License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16
17 #ifdef HAVE_CONFIG_H
18 #  include "config.h"
19 #endif
20
21 #include "WindowBuilder.hxx"
22
23 #include "WindowSystemAdapter.hxx"
24 #include <Main/fg_props.hxx>
25
26 #include <sstream>
27
28 using namespace std;
29 using namespace osg;
30
31 namespace flightgear
32 {
33 string makeName(const string& prefix, int num)
34 {
35     stringstream stream;
36     stream << prefix << num;
37     return stream.str();
38 }
39
40 ref_ptr<WindowBuilder> WindowBuilder::windowBuilder;
41
42 const string WindowBuilder::defaultWindowName("FlightGear");
43
44 void WindowBuilder::initWindowBuilder(bool stencil)
45 {
46     windowBuilder = new WindowBuilder(stencil);
47 }
48
49 WindowBuilder::WindowBuilder(bool stencil) : defaultCounter(0)
50 {
51     defaultTraits = makeDefaultTraits(stencil);
52 }
53
54 GraphicsContext::Traits*
55 WindowBuilder::makeDefaultTraits(bool stencil)
56 {
57     GraphicsContext::WindowingSystemInterface* wsi
58         = osg::GraphicsContext::getWindowingSystemInterface();
59     GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
60
61     traits->readDISPLAY();
62     if (traits->displayNum < 0)
63         traits->displayNum = 0;
64     if (traits->screenNum < 0)
65         traits->screenNum = 0;
66
67     int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
68     bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
69     int cbits = (bpp <= 16) ?  5 :  8;
70     int zbits = (bpp <= 16) ? 16 : 24;
71     traits->red = traits->green = traits->blue = cbits;
72     traits->depth = zbits;
73     if (alpha)
74         traits->alpha = 8;
75
76     if (stencil)
77         traits->stencil = 8;
78
79     unsigned screenwidth = 0;
80     unsigned screenheight = 0;
81     wsi->getScreenResolution(*traits, screenwidth, screenheight);
82
83     traits->doubleBuffer = true;
84     traits->mipMapGeneration = true;
85     traits->windowName = "FlightGear";
86     // XXX should check per window too.
87     traits->sampleBuffers = fgGetInt("/sim/rendering/multi-sample-buffers", traits->sampleBuffers);
88     traits->samples = fgGetInt("/sim/rendering/multi-samples", traits->samples);
89     traits->vsync = fgGetBool("/sim/rendering/vsync-enable", traits->vsync);
90     traits->windowDecoration = !fgGetBool("/sim/startup/fullscreen");
91
92     if (!traits->windowDecoration) {
93         // fullscreen
94         traits->supportsResize = false;
95         traits->width = screenwidth;
96         traits->height = screenheight;
97         SG_LOG(SG_VIEW,SG_DEBUG,"Using full screen size for window: " << screenwidth << " x " << screenheight);
98     } else {
99         // window
100         int w = fgGetInt("/sim/startup/xsize");
101         int h = fgGetInt("/sim/startup/ysize");
102         traits->supportsResize = true;
103         traits->width = w;
104         traits->height = h;
105         if ((w>0)&&(h>0))
106         {
107             traits->x = ((unsigned)w>screenwidth) ? 0 : (screenwidth-w)/3;
108             traits->y = ((unsigned)h>screenheight) ? 0 : (screenheight-h)/3;
109         }
110         SG_LOG(SG_VIEW,SG_DEBUG,"Using initial window size: " << w << " x " << h);
111     }
112     return traits;
113 }
114 }
115
116 namespace
117 {
118 // Helper functions that set a value based on a property if it exists,
119 // returning 1 if the value was set.
120
121 inline int setFromProperty(string& place, const SGPropertyNode* node,
122                             const char* name)
123 {
124     const SGPropertyNode* valNode = node->getNode(name);
125     if (valNode) {
126         place = valNode->getStringValue();
127         return 1;
128     }
129     return 0;
130 }
131
132 inline int setFromProperty(int& place, const SGPropertyNode* node,
133                             const char* name)
134 {
135     const SGPropertyNode* valNode = node->getNode(name);
136     if (valNode) {
137         place = valNode->getIntValue();
138         return 1;
139     }
140     return 0;
141 }
142
143 inline int setFromProperty(bool& place, const SGPropertyNode* node,
144                             const char* name)
145 {
146     const SGPropertyNode* valNode = node->getNode(name);
147     if (valNode) {
148         place = valNode->getBoolValue();
149         return 1;
150     }
151     return 0;
152 }
153 }
154
155 namespace flightgear
156 {
157 GraphicsWindow* WindowBuilder::buildWindow(const SGPropertyNode* winNode)
158 {
159     GraphicsContext::WindowingSystemInterface* wsi
160         = osg::GraphicsContext::getWindowingSystemInterface();
161     WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
162     string windowName;
163     if (winNode->hasChild("window-name"))
164         windowName = winNode->getStringValue("window-name");
165     else if (winNode->hasChild("name"))
166         windowName = winNode->getStringValue("name");
167     GraphicsWindow* result = 0;
168     if (!windowName.empty()) {
169         result = wsa->findWindow(windowName);
170         if (result)
171             return result;
172     }
173     GraphicsContext::Traits* traits
174         = new GraphicsContext::Traits(*defaultTraits);
175     int traitsSet = setFromProperty(traits->hostName, winNode, "host-name");
176     traitsSet |= setFromProperty(traits->displayNum, winNode, "display");
177     traitsSet |= setFromProperty(traits->screenNum, winNode, "screen");
178
179     const SGPropertyNode* fullscreenNode = winNode->getNode("fullscreen");
180
181     if (fullscreenNode && fullscreenNode->getBoolValue()) {
182         // fullscreen mode
183         unsigned width = 0;
184         unsigned height = 0;
185         wsi->getScreenResolution(*traits, width, height);
186         traits->windowDecoration = false;
187         traits->width = width;
188         traits->height = height;
189         traits->supportsResize = false;
190         traits->x = 0;
191         traits->y = 0;
192         traitsSet = 1;
193     } else {
194         int resizable = 0;
195         if (fullscreenNode && !fullscreenNode->getBoolValue())
196         {
197             traits->windowDecoration = true;
198             resizable = 1;
199         }
200         resizable |= setFromProperty(traits->windowDecoration, winNode,
201                                      "decoration");
202         resizable |= setFromProperty(traits->width, winNode, "width");
203         resizable |= setFromProperty(traits->height, winNode, "height");
204         if (resizable) {
205             traits->supportsResize = true;
206             traitsSet = 1;
207         }
208         // Otherwise use default values.
209     }
210     traitsSet |= setFromProperty(traits->x, winNode, "x");
211     traitsSet |= setFromProperty(traits->y, winNode, "y");
212     if (!windowName.empty() && windowName != traits->windowName) {
213         traits->windowName = windowName;
214         traitsSet = 1;
215     } else if (traitsSet) {
216         traits->windowName = makeName("FlightGear", defaultCounter++);
217     }
218     bool drawGUI = false;
219     traitsSet |= setFromProperty(drawGUI, winNode, "gui");
220     if (traitsSet) {
221         GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
222         if (gc) {
223             GraphicsWindow* window = WindowSystemAdapter::getWSA()
224                 ->registerWindow(gc, traits->windowName);
225             if (drawGUI)
226                 window->flags |= GraphicsWindow::GUI;
227             return window;
228         } else {
229             return 0;
230         }
231     } else {
232         // XXX What if the window has no traits, but does have a name?
233         // We should create a "default window" registered with that name.
234         return getDefaultWindow();
235     }
236 }
237
238 GraphicsWindow* WindowBuilder::getDefaultWindow()
239 {
240     GraphicsWindow* defaultWindow
241         = WindowSystemAdapter::getWSA()->findWindow(defaultWindowName);
242     if (defaultWindow)
243         return defaultWindow;
244     GraphicsContext::Traits* traits
245         = new GraphicsContext::Traits(*defaultTraits);
246     traits->windowName = "FlightGear";
247     
248     GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
249     if (gc) {
250         defaultWindow = WindowSystemAdapter::getWSA()
251             ->registerWindow(gc, defaultWindowName);
252         return defaultWindow;
253     } else {
254         SG_LOG(SG_VIEW, SG_ALERT, "getDefaultWindow: failed to create GraphicsContext");
255         return 0;
256     }
257 }
258 }