]> git.mxchange.org Git - flightgear.git/blob - src/Main/WindowBuilder.cxx
Merge branch 'ehofman/particle' into next
[flightgear.git] / src / Main / 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 #include "WindowBuilder.hxx"
18
19 #include "WindowSystemAdapter.hxx"
20 #include "fg_props.hxx"
21
22 #include <sstream>
23
24 using namespace std;
25 using namespace osg;
26
27 namespace flightgear
28 {
29 string makeName(const string& prefix, int num)
30 {
31     stringstream stream;
32     stream << prefix << num;
33     return stream.str();
34 }
35
36 ref_ptr<WindowBuilder> WindowBuilder::windowBuilder;
37
38 const string WindowBuilder::defaultWindowName("FlightGear");
39
40 void WindowBuilder::initWindowBuilder(bool stencil)
41 {
42     windowBuilder = new WindowBuilder(stencil);
43 }
44
45 WindowBuilder::WindowBuilder(bool stencil) : defaultCounter(0)
46 {
47     defaultTraits = makeDefaultTraits(stencil);
48 }
49
50 GraphicsContext::Traits*
51 WindowBuilder::makeDefaultTraits(bool stencil)
52 {
53     GraphicsContext::WindowingSystemInterface* wsi
54         = osg::GraphicsContext::getWindowingSystemInterface();
55     int w = fgGetInt("/sim/startup/xsize");
56     int h = fgGetInt("/sim/startup/ysize");
57     int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
58     bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
59     bool fullscreen = fgGetBool("/sim/startup/fullscreen");
60
61     GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
62     traits->readDISPLAY();
63     int cbits = (bpp <= 16) ?  5 :  8;
64     int zbits = (bpp <= 16) ? 16 : 24;
65     traits->red = traits->green = traits->blue = cbits;
66     traits->depth = zbits;
67     if (alpha)
68         traits->alpha = 8;
69     if (stencil)
70         traits->stencil = 8;
71     traits->doubleBuffer = true;
72     traits->mipMapGeneration = true;
73     traits->windowName = "FlightGear";
74     // XXX should check per window too.
75     traits->sampleBuffers = fgGetBool("/sim/rendering/multi-sample-buffers", traits->sampleBuffers);
76     traits->samples = fgGetInt("/sim/rendering/multi-samples", traits->samples);
77     traits->vsync = fgGetBool("/sim/rendering/vsync-enable", traits->vsync);
78     if (fullscreen) {
79         unsigned width = 0;
80         unsigned height = 0;
81         wsi->getScreenResolution(*traits, width, height);
82         traits->windowDecoration = false;
83         traits->width = width;
84         traits->height = height;
85         traits->supportsResize = false;
86     } else {
87         traits->windowDecoration = true;
88         traits->width = w;
89         traits->height = h;
90 #if defined(WIN32) || defined(__APPLE__)
91         // Ugly Hack, why does CW_USEDEFAULT works like phase of the moon?
92         // Mac also needs this to show window frame, menubar and Docks
93         traits->x = 100;
94         traits->y = 100;
95 #endif
96         traits->supportsResize = true;
97     }
98     return traits;
99 }
100 }
101
102 namespace
103 {
104 // Helper functions that set a value based on a property if it exists,
105 // returning 1 if the value was set.
106
107 inline int setFromProperty(string& place, const SGPropertyNode* node,
108                             const char* name)
109 {
110     const SGPropertyNode* valNode = node->getNode(name);
111     if (valNode) {
112         place = valNode->getStringValue();
113         return 1;
114     }
115     return 0;
116 }
117
118 inline int setFromProperty(int& place, const SGPropertyNode* node,
119                             const char* name)
120 {
121     const SGPropertyNode* valNode = node->getNode(name);
122     if (valNode) {
123         place = valNode->getIntValue();
124         return 1;
125     }
126     return 0;
127 }
128
129 inline int setFromProperty(bool& place, const SGPropertyNode* node,
130                             const char* name)
131 {
132     const SGPropertyNode* valNode = node->getNode(name);
133     if (valNode) {
134         place = valNode->getBoolValue();
135         return 1;
136     }
137     return 0;
138 }
139 }
140
141 namespace flightgear
142 {
143 GraphicsWindow* WindowBuilder::buildWindow(const SGPropertyNode* winNode)
144 {
145     GraphicsContext::WindowingSystemInterface* wsi
146         = osg::GraphicsContext::getWindowingSystemInterface();
147     WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
148     string windowName;
149     if (winNode->hasChild("window-name"))
150         windowName = winNode->getStringValue("window-name");
151     else if (winNode->hasChild("name")) 
152         windowName = winNode->getStringValue("name");
153     GraphicsWindow* result = 0;
154     if (!windowName.empty()) {
155         result = wsa->findWindow(windowName);
156         if (result)
157             return result;
158     }
159     GraphicsContext::Traits* traits
160         = new GraphicsContext::Traits(*defaultTraits);
161     int traitsSet = setFromProperty(traits->hostName, winNode, "host-name");
162     traitsSet |= setFromProperty(traits->displayNum, winNode, "display");
163     traitsSet |= setFromProperty(traits->screenNum, winNode, "screen");
164     const SGPropertyNode* fullscreenNode = winNode->getNode("fullscreen");
165     if (fullscreenNode && fullscreenNode->getBoolValue()) {
166         unsigned width = 0;
167         unsigned height = 0;
168         wsi->getScreenResolution(*traits, width, height);
169         traits->windowDecoration = false;
170         traits->width = width;
171         traits->height = height;
172         traits->supportsResize = false;
173         traitsSet = 1;
174     } else {
175         int resizable = 0;
176         resizable |= setFromProperty(traits->windowDecoration, winNode,
177                                      "decoration");
178         resizable |= setFromProperty(traits->width, winNode, "width");
179         resizable |= setFromProperty(traits->height, winNode, "height");
180         if (resizable) {
181             traits->supportsResize = true;
182             traitsSet = 1;
183         }
184         // Otherwise use default values.
185     }
186     traitsSet |= setFromProperty(traits->x, winNode, "x");
187     traitsSet |= setFromProperty(traits->y, winNode, "y");
188     if (!windowName.empty() && windowName != traits->windowName) {
189         traits->windowName = windowName;
190         traitsSet = 1;
191     } else if (traitsSet) {
192         traits->windowName = makeName("FlightGear", defaultCounter++);
193     }
194     bool drawGUI = false;
195     traitsSet |= setFromProperty(drawGUI, winNode, "gui");
196     if (traitsSet) {
197         GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
198         if (gc) {
199             GraphicsWindow* window = WindowSystemAdapter::getWSA()
200                 ->registerWindow(gc, traits->windowName);
201             if (drawGUI)
202                 window->flags |= GraphicsWindow::GUI;
203             return window;
204         } else {
205             return 0;
206         }
207     } else {
208         // XXX What if the window has no traits, but does have a name?
209         // We should create a "default window" registered with that name.
210         return getDefaultWindow();
211     }
212 }
213
214 GraphicsWindow* WindowBuilder::getDefaultWindow()
215 {
216     GraphicsWindow* defaultWindow
217         = WindowSystemAdapter::getWSA()->findWindow(defaultWindowName);
218     if (defaultWindow)
219         return defaultWindow;
220     GraphicsContext::Traits* traits
221         = new GraphicsContext::Traits(*defaultTraits);
222     traits->windowName = "FlightGear";
223     GraphicsContext* gc = GraphicsContext::createGraphicsContext(traits);
224     if (gc) {
225         defaultWindow = WindowSystemAdapter::getWSA()
226             ->registerWindow(gc, defaultWindowName);
227         return defaultWindow;
228     } else {
229         return 0;
230     }
231 }
232 }