MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gamewindow.cpp
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _graphicsgamewindow_cpp
41 #define _graphicsgamewindow_cpp
42 
43 #include "datatypes.h"
44 #include "Graphics/gamewindow.h"
45 #include "crossplatform.h"
46 #include "Graphics/viewport.h"
47 #include "Graphics/cameraproxy.h"
48 #include "graphicsmanager.h"
49 #include "entresol.h"
50 
51 #ifdef WINDOWS
52 #include <windows.h>
53 #endif
54 
55 #ifdef LINUX
56 #include <X11/X.h> //x11proto-core-dev
57 #include <X11/Xlib.h> //libx11-dev
58 #endif
59 
60 #ifdef MACOSX
61 #include <Cocoa/Cocoa.h>
62 #endif
63 
64 #include <SDL.h>
65 #include "../src/video/SDL_sysvideo.h"
66 #include <Ogre.h>
67 
68 namespace Mezzanine
69 {
70  namespace Graphics
71  {
72  GameWindow::GameWindow(const String& WindowCaption, const Whole Width, const Whole Height, const Whole Flags) :
73  OgreWindow(NULL),
74  SDLWindow(NULL)
75  { this->CreateGameWindow(WindowCaption,Width,Height,Flags); }
76 
78  {
79  // first lets clear out the user data manually, the alternative is using SDL's allocation methods to make it, which we can opt for later
80  if( this->SDLWindow ) {
81  SDL_WindowUserData* WindowData = this->SDLWindow->data;
82  this->SDLWindow->data = NULL;
83  delete WindowData;
84 
85  SDL_DestroyWindow(this->SDLWindow);
86  }
87 
88  //this->OgreWindow->destroy();
89  Ogre::Root::getSingleton().destroyRenderTarget(OgreWindow);
90  }
91 
92  void GameWindow::CreateGameWindow(const String& WindowCaption, const Whole Width, const Whole Height, const Whole Flags)
93  {
95  this->CreationFlags = Flags;
96  this->Settings.RenderWidth = Width;
97  this->Settings.RenderHeight = Height;
98 
100  if(WF_Fullscreen & Flags) {
101  this->Settings.Fullscreen = true;
102  }
103 
104  if(WF_Hidden & Flags) {
105  Opts["hidden"] = "true";
106  }
107 
108  if(WF_VsyncEnabled & Flags) {
109  Opts["vsync"] = "true";
110  this->Settings.VSync = true;
111  }
112 
113  if(WF_FSAA_16 & Flags) {
114  Opts["FSAA"] = "16";
115  }else if(WF_FSAA_8 & Flags) {
116  Opts["FSAA"] = "8";
117  }else if(WF_FSAA_4 & Flags) {
118  Opts["FSAA"] = "4";
119  }else if(WF_FSAA_2 & Flags) {
120  Opts["FSAA"] = "2";
121  }
122 
123  if(WF_Resizeable & Flags) {
124  Opts["border"] = "resize";
125  }else if(WF_Borderless & Flags) {
126  Opts["border"] = "none";
127  }else{
128  Opts["border"] = "fixed";
129  }
130 
131  if(WF_Maximized & Flags) {
132 
133  }
134 
135  #ifdef MACOSX
136  Opts["macAPI"] = "cocoa";
137  #endif
138 
139  //#ifdef LINUX
140  //Ogre::ResourceGroupManager::getSingleton().addResourceLocation(ResourceManager::GetSingletonPtr()->GetEngineDataDirectory(),"FileSystem");
141  //#endif
142  this->OgreWindow = Ogre::Root::getSingleton().createRenderWindow(WindowCaption, this->Settings.RenderWidth, this->Settings.RenderHeight, this->Settings.Fullscreen, &Opts);//*/
143 
144  if( !(WF_Hidden & Flags) ) {
145  #ifdef WINDOWS
146  HWND Data = 0;
147  #endif
148  #ifdef LINUX
149  Window Data = 0;
150  #endif
151  #ifdef MACOSX
152  NSWindow* Data = 0;
153  #endif
154  this->OgreWindow->getCustomAttribute("WINDOW",&Data);
155  this->SDLWindow = SDL_CreateWindowFrom((void*)Data);
156  this->SDLWindow->data = new SDL_WindowUserData();
157  this->SDLWindow->data->name = NULL;
158  this->SDLWindow->data->data = this;
159  this->SDLWindow->data->next = NULL;
160  }
161  }
162 
164  {
165  for( ViewportIterator ViewIt = this->Viewports.begin() ; ViewIt != this->Viewports.end() ; ++ViewIt )
166  {
167  CameraProxy* Cam = (*ViewIt)->GetViewportCamera();
168  if(Cam)
169  Cam->SetAspectRatio((Real)((*ViewIt)->GetActualWidth()) / (Real)((*ViewIt)->GetActualHeight()));
170  }
171  }
172 
173  int GameWindow::IsLargerThenDesktop(const Whole Width, const Whole Height)
174  {
175  SDL_DisplayMode DesktopDisplay;
176  SDL_GetDesktopDisplayMode(0,&DesktopDisplay);
177  if(Width > Whole(DesktopDisplay.w) || Height > Whole(DesktopDisplay.h))
178  return 1;
179  else if(Width == Whole(DesktopDisplay.w) || Height == Whole(DesktopDisplay.h))
180  return 0;
181  else
182  return -1;
183  }
184 
185  ///////////////////////////////////////////////////////////////////////////////
186  // Viewport Management
187 
188  Viewport* GameWindow::CreateViewport(CameraProxy* ViewportCamera, const Integer ZOrder)
189  {
190  Viewport* NewViewport = new Viewport(ViewportCamera,ZOrder,this);
191 
192  for( ViewportIterator ViewIt = this->Viewports.begin() ; ViewIt != this->Viewports.end() ; ++ViewIt )
193  {
194  if( (*ViewIt)->GetZOrder() > ZOrder ) {
195  this->Viewports.insert( ViewIt, NewViewport );
196  return NewViewport;
197  }
198  }
199 
200  this->Viewports.push_back( NewViewport );
201  return NewViewport;
202  }
203 
205  {
206  Whole Count = Index;
207  ConstViewportIterator ViewIt = this->Viewports.begin();
208  while( Count-- )
209  ++ViewIt;
210 
211  return (*ViewIt);
212  }
213 
215  {
216  for( ConstViewportIterator ViewIt = this->Viewports.begin() ; ViewIt != this->Viewports.end() ; ++ViewIt )
217  {
218  if( (*ViewIt)->GetZOrder() == ZOrder ) {
219  return (*ViewIt);
220  }
221  }
222  return NULL;
223  }
224 
226  {
227  return this->Viewports.size();
228  }
229 
231  {
232  for ( ViewportIterator ViewIt = this->Viewports.begin() ; ViewIt != this->Viewports.end() ; ++ViewIt )
233  {
234  if ( ToBeDestroyed == (*ViewIt) ) {
235  delete ToBeDestroyed;
236  this->Viewports.erase(ViewIt);
237  return;
238  }
239  }
240  }
241 
243  { return this->Viewports.begin(); }
244 
246  { return this->Viewports.end(); }
247 
249  { return this->Viewports.begin(); }
250 
252  { return this->Viewports.end(); }
253 
255  { return this->Viewports.rbegin(); }
256 
258  { return this->Viewports.rend(); }
259 
261  { return this->Viewports.rbegin(); }
262 
264  { return this->Viewports.rend(); }
265 
266  ///////////////////////////////////////////////////////////////////////////////
267  // Window Metrics Management
268 
270  {
271  if( this->Settings.RenderWidth == Width )
272  return;
273  this->SetRenderResolution(Width,this->Settings.RenderHeight);
274  this->Settings.RenderWidth = Width;
275  }
276 
278  {
279  return this->Settings.RenderWidth;
280  }
281 
282  void GameWindow::SetRenderHeight(const Whole& Height)
283  {
284  if( this->Settings.RenderHeight == Height )
285  return;
286  this->SetRenderResolution(this->Settings.RenderWidth,Height);
287  this->Settings.RenderHeight = Height;
288  }
289 
291  {
292  return this->Settings.RenderHeight;
293  }
294 
295  void GameWindow::SetRenderResolution(const Whole& Width, const Whole& Height)
296  {
297  if( this->Settings.RenderWidth == Width && this->Settings.RenderHeight == Height )
298  return;
299  if( this->Settings.Fullscreen ) {
300  SDL_DisplayMode CurrentDisplay;
301  SDL_GetWindowDisplayMode(SDLWindow,&CurrentDisplay);
302  CurrentDisplay.w = Width;
303  CurrentDisplay.h = Height;
304  // ©urrentDisplay.refresh_rate = 60;
305  if(SDL_SetWindowDisplayMode(SDLWindow,&CurrentDisplay) == 0)
306  {
307  this->OgreWindow->setFullscreen(true,Width,Height);
309  this->Settings.RenderWidth = Width;
310  this->Settings.RenderHeight = Height;
311  return;
312  }
313  }else{
314  int Result = this->IsLargerThenDesktop(Width,Height);
315  if(Result == 0) {
316  Whole ResultWidth, ResultHeight;
317  crossplatform::SanitizeWindowedRes(Width,Height,ResultWidth,ResultHeight);
318  SDL_SetWindowSize(SDLWindow,ResultWidth,ResultHeight);
319  this->OgreWindow->setFullscreen(false,ResultWidth,ResultHeight);
320  }else if(Result == 1){
321  Entresol::GetSingletonPtr()->Log("Cannot create a window larger then the desktop resolution.");
322  return;
323  }else{
324  SDL_SetWindowSize(SDLWindow,Width,Height);
325  this->OgreWindow->setFullscreen(false,Width,Height);
326  }
328  this->Settings.RenderWidth = Width;
329  this->Settings.RenderHeight = Height;
330  }
331  }
332 
333  void GameWindow::SetFullscreen(const bool Fullscreen)
334  {
335  static SDL_DisplayMode FSDisplayMode;
336 
337  if( Fullscreen == this->Settings.Fullscreen )
338  return;
339 
340  if( !Fullscreen && this->Settings.Fullscreen ) {
341  const WindowSettings& DeskSet = this->Manager->GetDesktopSettings();
342  if( this->Settings.RenderWidth > DeskSet.RenderWidth || this->Settings.RenderHeight > DeskSet.RenderHeight ) {
343  this->Settings.RenderWidth = DeskSet.RenderWidth;
344  this->Settings.RenderHeight = DeskSet.RenderHeight;
345  }
346  if( this->Settings.RenderWidth == DeskSet.RenderWidth || this->Settings.RenderHeight == DeskSet.RenderHeight ) {
347  Whole ResultWidth, ResultHeight;
349  this->SetRenderResolution(ResultWidth,ResultHeight);
350  this->Settings.RenderWidth = DeskSet.RenderWidth;
351  this->Settings.RenderHeight = DeskSet.RenderHeight;
352  }
353  }else if(Fullscreen && !Settings.Fullscreen) {
354  FSDisplayMode.w = this->Settings.RenderWidth;
355  FSDisplayMode.h = this->Settings.RenderHeight;
356  FSDisplayMode.refresh_rate = Settings.RefreshRate;
357  SDL_SetWindowDisplayMode(SDLWindow,&FSDisplayMode);
358  }
359 
360  if(SDL_SetWindowFullscreen(SDLWindow, Fullscreen?SDL_TRUE:SDL_FALSE ) == 0) {
361  this->OgreWindow->setFullscreen(Fullscreen,this->Settings.RenderWidth,this->Settings.RenderHeight);
363  this->Settings.Fullscreen = Fullscreen;
364  }
365  }
366 
368  {
369  return this->Settings.Fullscreen;
370  }
371 
373  {
374  this->SetFullscreen( NewSettings.Fullscreen );
375  this->SetRenderResolution( NewSettings.RenderWidth, NewSettings.RenderHeight );
376  }
377 
379  {
380  return this->Settings;
381  }
382 
383  ///////////////////////////////////////////////////////////////////////////////
384  // Window Settings Methods
385 
387  { return this->OgreWindow->getName(); }
388 
390  { return this->OgreWindow->getFSAA(); }
391 
392  void GameWindow::EnableVsync(bool Enable)
393  { this->OgreWindow->setVSyncEnabled(Enable); }
394 
395  Boolean GameWindow::VsyncEnabled() const
396  { return this->OgreWindow->isVSyncEnabled(); }
397 
398  void GameWindow::SetHidden(bool Hidden)
399  { this->OgreWindow->setHidden(Hidden); }
400 
401  Boolean GameWindow::IsHidden() const
402  { return this->OgreWindow->isHidden(); }
403 
405  { return (this->CreationFlags & GameWindow::WF_Resizeable); }
406 
407  Boolean GameWindow::IsBorderless() const
408  { return (this->CreationFlags & GameWindow::WF_Borderless); }
409 
410  ///////////////////////////////////////////////////////////////////////////////
411  // Window Stats Methods
412 
414  { return this->OgreWindow->getLastFPS(); }
415 
417  { return this->OgreWindow->getAverageFPS(); }
418 
420  { return this->OgreWindow->getBestFPS(); }
421 
423  { return this->OgreWindow->getWorstFPS(); }
424 
426  { return this->OgreWindow->getBestFrameTime(); }
427 
429  { return this->OgreWindow->getWorstFrameTime(); }
430 
431  ///////////////////////////////////////////////////////////////////////////////
432  // Internal Methods
433 
434  Ogre::RenderWindow* GameWindow::_GetOgreWindowPointer()
435  { return this->OgreWindow; }
436 
438  { return this->SDLWindow; }
439  }//Graphics
440 }//Mezzanine
441 
442 #endif