00001
00007 #include "SO3Window.h"
00008 #include "SO3ViewPort.h"
00009 #include <scol.h>
00010 #include "../SO3Renderer/SO3Root.h"
00011 #include "../SO3SceneGraph/SO3Camera.h"
00012 #include "../SO3SceneGraph/SO3SubEntitySelectorBuffer.h"
00013 #include "../SO3Utils/SO3ConversionTools.h"
00014
00018 extern WindowHandle hwndScol;
00019 extern int BUFFER_PRE_RENDER_EVENT;
00020 extern int BUFFER_POST_RENDER_EVENT;
00021
00022 namespace SO3
00023 {
00024 SWindow::SWindow() : SData("")
00025 {
00026
00027 }
00028
00029 SWindow::SWindow(SRoot* parent, WindowHandle windowHandle, std::string windowName, int width, int height, std::string fsaa) : SData(windowName)
00030 {
00031 scolRoot = parent;
00032 bBeginFrame = false;
00033
00034
00035 hwnd = windowHandle;
00036 Ogre::String winHandle = Ogre::StringConverter::toString((size_t)(WindowHandle)hwnd);
00037
00038
00039 SetWindowLongPtr(hwnd, GWL_STYLE, (GetWindowLongPtr(hwnd, GWL_STYLE))|WS_CLIPCHILDREN);
00040
00041
00042 Ogre::NameValuePairList viewConfig;
00043 viewConfig["externalWindowHandle"] = winHandle;
00044
00045
00046 viewConfig["monitorIndex"] = "0";
00047 viewConfig["vsync"] = "Yes";
00048
00049 #ifdef SO3_DEBUG
00050 viewConfig["useNVPerfHUD"] = "Yes";
00051 #endif
00052
00053
00054 if(scolRoot->checkFSAA(fsaa))
00055 {
00056 if(fsaa.find("[Quality]") != string::npos)
00057 {
00058 viewConfig["FSAAHint"] = "Quality";
00059 viewConfig["FSAA"] = fsaa.substr(0, fsaa.find("[Quality]")-2);
00060 }
00061 else
00062 {
00063 viewConfig["FSAA"] = fsaa;
00064 viewConfig["FSAAHint"] = "";
00065 }
00066 }
00067
00068 O3Window = Ogre::Root::getSingleton().createRenderWindow(windowName, width, height, false, &viewConfig);
00069 O3Window->setPriority(0);
00070
00071
00072 if(O3Window->isPrimary())
00073 scolRoot->InitRenderer();
00074
00075 O3Window->addListener(this);
00076 O3StereoManager = new Ogre::StereoManager();
00077 hwndFullscreenOgre = NULL;
00078 styleFullscreenOgre = NULL;
00079 exstyleFullscreenOgre = NULL;
00080 currentStereoMode = SWindow::SO3_NONE_STEREO;
00081
00082 subEntitySelector = new SSubEntitySelectorBuffer(this);
00083
00084
00085 O3Window->update();
00086 }
00087
00088 SWindow::~SWindow()
00089 {
00090 O3Window->removeListener(this);
00091 SAFE_DELETE(subEntitySelector);
00092 SAFE_DELETE(O3StereoManager);
00093
00094
00095 SetWindowLongPtr(hwnd, GWL_STYLE, (GetWindowLongPtr(hwnd, GWL_STYLE))& ~(WS_CLIPCHILDREN));
00096
00097
00098 if((scolRoot->GetRenderSystem() == SRoot::SO3_OPENGL_RENDERER) || ((scolRoot->GetRenderSystem() != SRoot::SO3_OPENGL_RENDERER) && !O3Window->isPrimary()))
00099 {
00100 Ogre::Root::getSingleton().detachRenderTarget(GetName());
00101 O3Window->destroy();
00102 }
00103
00104 O3Window = 0;
00105 }
00106
00107 void SWindow::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
00108 {
00109 if(subEntitySelector)
00110 subEntitySelector->NeedUpdate();
00111 SendMessage(hwndScol, BUFFER_PRE_RENDER_EVENT, (int)this,(LPARAM)NULL);
00112 }
00113
00114 void SWindow::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
00115 {
00116 SendMessage(hwndScol, BUFFER_POST_RENDER_EVENT, (int)this,(LPARAM)NULL);
00117 }
00118
00119 void SWindow::RefreshSelector()
00120 {
00121 if (subEntitySelector)
00122 subEntitySelector->ForceUpdate();
00123 }
00124
00125 WindowHandle SWindow::GetWindowHandle()
00126 {
00127 return hwnd;
00128 }
00129
00130 SRoot* SWindow::GetParentRoot()
00131 {
00132 return scolRoot;
00133 }
00134
00135 const Ogre::RenderWindow* SWindow::GetOgreRenderWindowPointer()
00136 {
00137 return O3Window;
00138 }
00139
00140 SViewPort* SWindow::CreateViewport(SCamera* camera, int priority, float x, float y, float w, float h)
00141 {
00142 SViewPort* newViewport = new SViewPort(this, camera, priority, x, y, w, h);
00143 AddViewport(newViewport);
00144 return newViewport;
00145 }
00146
00147 void SWindow::DeleteViewport(SViewPort* existingViewport)
00148 {
00149 RemoveViewport(existingViewport);
00150 SAFE_DELETE(existingViewport);
00151 }
00152
00153 void SWindow::AddViewport(SViewPort* existingViewport)
00154 {
00155 SViewPortList::iterator iViewportSearched = listOfViewPort.find(existingViewport->GetPriority());
00156 if(iViewportSearched == listOfViewPort.end())
00157 {
00158 listOfViewPort.insert(SViewPortList::value_type(existingViewport->GetPriority(), existingViewport));
00159 if (subEntitySelector != 0)
00160 subEntitySelector->AddViewport(existingViewport);
00161 }
00162 else
00163 {
00164
00165 OGRE_EXCEPT(Ogre::Exception::ERR_DUPLICATE_ITEM, "Can not add Viewport, an identical element with the same priority already exist!", "SWindow::AddViewport");
00166 }
00167 }
00168
00169 void SWindow::RemoveViewport(SViewPort* existingViewport)
00170 {
00171 SViewPortList::iterator iViewportSearched = listOfViewPort.find(existingViewport->GetPriority());
00172 if(iViewportSearched != listOfViewPort.end())
00173 {
00174 listOfViewPort.erase(iViewportSearched);
00175 if (subEntitySelector != 0)
00176 subEntitySelector->RemoveViewport(existingViewport);
00177 }
00178 else
00179 {
00180
00181 OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Can not remove Viewport, element not found!", "SWindow::RemoveViewport");
00182 }
00183 }
00184
00185 const SViewPortList& SWindow::GetViewportList() const
00186 {
00187 return listOfViewPort;
00188 }
00189
00190 SViewPort* SWindow::GetViewport(int priority) const
00191 {
00192 SViewPort* existingViewport = 0;
00193 SViewPortList::const_iterator iViewportSearched = listOfViewPort.find(priority);
00194 if(iViewportSearched != listOfViewPort.end())
00195 {
00196 existingViewport = iViewportSearched->second;
00197 }
00198 else
00199 {
00200
00201 OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Can not find Viewport with this priority, windows do not have such element!", "SWindow::GetViewport");
00202 }
00203 return existingViewport;
00204 }
00205
00206 SViewPort* SWindow::GetViewport(int x, int y)
00207 {
00208 int highestZ = 0;
00209 SViewPort* resultViewport = 0;
00210
00211 SViewPortList::iterator iViewport = listOfViewPort.begin();
00212 while(iViewport != listOfViewPort.end())
00213 {
00214 int curZ = iViewport->second->GetPriority();
00215 int left = iViewport->second->GetLeftPixels();
00216 int top = iViewport->second->GetTopPixels();
00217 int width = iViewport->second->GetWidthPixels();
00218 int height = iViewport->second->GetHeightPixels();
00219
00220 if(((x >= left)&&(y >= top)&&(x <= left + width)&&(y <= top + height)) && curZ >= highestZ)
00221 {
00222 resultViewport = iViewport->second;
00223 highestZ = curZ;
00224 }
00225
00226 iViewport++;
00227 }
00228
00229 return resultViewport;
00230 }
00231
00232 void SWindow::windowMoved(Ogre::RenderWindow* rw)
00233 {
00234 }
00235
00236 void SWindow::windowResized(Ogre::RenderWindow* rw)
00237 {
00238 }
00239
00240 void SWindow::windowClosed(Ogre::RenderWindow* rw)
00241 {
00242 }
00243
00244 void SWindow::windowFocusChange(Ogre::RenderWindow* rw)
00245 {
00246 }
00247
00248 int SWindow::Size(int x,int y,int w,int h,int ext)
00249 {
00250 O3Window->resize(w,h);
00251 O3Window->reposition(x,y);
00252 O3Window->windowMovedOrResized();
00253
00254
00255 Ogre::WindowEventUtilities::WindowEventListeners::iterator index;
00256 Ogre::WindowEventUtilities::WindowEventListeners::iterator start = Ogre::WindowEventUtilities::_msListeners.lower_bound(O3Window);
00257 Ogre::WindowEventUtilities::WindowEventListeners::iterator end = Ogre::WindowEventUtilities::_msListeners.upper_bound(O3Window);
00258 for(index = start; index != end; ++index)
00259 (index->second)->windowResized(O3Window);
00260
00261 return 0;
00262 }
00263
00264 void SWindow::WindowMovedOrResized()
00265 {
00266 WINDOWPLACEMENT curWinPos;
00267
00268 GetWindowPlacement(hwnd, &curWinPos);
00269 Size(curWinPos.rcNormalPosition.left, curWinPos.rcNormalPosition.top, curWinPos.rcNormalPosition.right - curWinPos.rcNormalPosition.left, curWinPos.rcNormalPosition.bottom - curWinPos.rcNormalPosition.top, 0);
00270 }
00271
00272 unsigned int SWindow::GetWidth() const
00273 {
00274 return O3Window->getWidth();
00275 }
00276
00277 unsigned int SWindow::GetHeight() const
00278 {
00279 return O3Window->getHeight();
00280 }
00281
00282 int SWindow::GetLeft()
00283 {
00284 unsigned int nullUintPtr;
00285 int left, nullIntPtr;
00286 O3Window->getMetrics(nullUintPtr, nullUintPtr, nullUintPtr, left, nullIntPtr);
00287 return left;
00288 }
00289
00290 int SWindow::GetTop()
00291 {
00292 unsigned int nullUintPtr;
00293 int top, nullIntPtr;
00294 O3Window->getMetrics(nullUintPtr, nullUintPtr, nullUintPtr, nullIntPtr, top);
00295 return top;
00296 }
00297
00298 bool SWindow::SetFullScreen(bool fullscreen, int width, int height)
00299 {
00300
00301 if(!fullscreen && O3Window->isFullScreen())
00302 {
00303 if((SRoot::getSingleton().SetFullScreenState(this, fullscreen, mLastPos.rcNormalPosition.right - mLastPos.rcNormalPosition.left, mLastPos.rcNormalPosition.bottom - mLastPos.rcNormalPosition.top)) == false)
00304 return false;
00305
00306
00307 SetWindowLongPtr(hwnd, GWL_STYLE, styleFullscreenOgre);
00308 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exstyleFullscreenOgre);
00309 SetParent(hwnd, (WindowHandle)hwndFullscreenOgre);
00310
00311
00312 Size(mLastPos.rcNormalPosition.left, mLastPos.rcNormalPosition.top, mLastPos.rcNormalPosition.right - mLastPos.rcNormalPosition.left, mLastPos.rcNormalPosition.bottom - mLastPos.rcNormalPosition.top, 0);
00313 WindowMovedOrResized();
00314 return true;
00315 }
00316 else if(fullscreen && !O3Window->isFullScreen())
00317 {
00318 if (!CheckVideoMode(width, height))
00319 {
00320 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS , "Invalid resolution parameters, fullscreen not setted", "SWindow::SetFullScreen");
00321 return false;
00322 }
00323
00324
00325 hwndFullscreenOgre = GetWindowLongPtr(hwnd, GWL_HWNDPARENT);
00326 styleFullscreenOgre = GetWindowLongPtr(hwnd, GWL_STYLE);
00327 exstyleFullscreenOgre = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
00328 GetWindowPlacement(hwnd, &mLastPos);
00329
00330
00331 SetParent(hwnd, NULL);
00332
00333
00334 if ((SRoot::getSingleton().SetFullScreenState(this, fullscreen, width, height)) == false)
00335 {
00336
00337 SetWindowLongPtr(hwnd, GWL_STYLE, styleFullscreenOgre);
00338 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exstyleFullscreenOgre);
00339 SetParent(hwnd, (WindowHandle)hwndFullscreenOgre);
00340
00341
00342 Size(mLastPos.rcNormalPosition.left, mLastPos.rcNormalPosition.top, mLastPos.rcNormalPosition.right - mLastPos.rcNormalPosition.left, mLastPos.rcNormalPosition.bottom - mLastPos.rcNormalPosition.top, 0);
00343 WindowMovedOrResized();
00344 return false;
00345 }
00346
00347 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_FRAMECHANGED|SWP_SHOWWINDOW);
00348 WindowMovedOrResized();
00349
00350 return true;
00351 }
00352 return false;
00353 }
00354
00355 bool SWindow::GetFullScreen()
00356 {
00357 return O3Window->isFullScreen();
00358 }
00359
00360 bool SWindow::CheckVideoMode(int width, int height)
00361 {
00362 bool vmc = false;
00363 char strW[16];
00364 char strH[16];
00365
00366 Ogre::ConfigOptionMap& m_system_caps = Ogre::Root::getSingleton().getRenderSystem()->getConfigOptions();
00367 Ogre::ConfigOptionMap::iterator itr = m_system_caps.begin();
00368 while(itr != m_system_caps.end() && !vmc)
00369 {
00370 if((itr)->first == "Video Mode" )
00371 {
00372 Ogre::StringVector possible_values = (itr)->second.possibleValues;
00373 Ogre::StringVector::iterator pv_itr = possible_values.begin();
00374 while(pv_itr != possible_values.end() && !vmc)
00375 {
00376 if(pv_itr->find(itoa(width, strW, 10)) != string::npos && pv_itr->find(itoa(height, strH, 10)) != string::npos && pv_itr->find(itoa(width, strW, 10))<pv_itr->find(itoa(height, strH, 10)))
00377 vmc = true;
00378
00379 pv_itr ++;
00380 }
00381 }
00382 itr ++;
00383 }
00384 return vmc;
00385 }
00386
00387 unsigned int SWindow::GetColorDepth()
00388 {
00389 return O3Window->getColourDepth();
00390 }
00391
00392 void SWindow::Update()
00393 {
00394 O3Window->update(true);
00395 }
00396
00397 unsigned int SWindow::GetBatchCount() const
00398 {
00399 return O3Window->getBatchCount();
00400 }
00401
00402 unsigned int SWindow::GetTriangleCount() const
00403 {
00404 return O3Window->getTriangleCount();
00405 }
00406
00407 float SWindow::GetBestFrameTime() const
00408 {
00409 return O3Window->getBestFrameTime();
00410 }
00411
00412 float SWindow::GetWorstFrameTime() const
00413 {
00414 return O3Window->getWorstFrameTime();
00415 }
00416
00417 float SWindow::GetBestFPS() const
00418 {
00419 return O3Window->getBestFPS();
00420 }
00421
00422 float SWindow::GetWorstFPS() const
00423 {
00424 return O3Window->getWorstFPS();
00425 }
00426
00427 float SWindow::GetAverageFPS() const
00428 {
00429 return O3Window->getAverageFPS();
00430 }
00431
00432 unsigned int SWindow::GetFSAA() const
00433 {
00434 return O3Window->getFSAA();
00435 }
00436
00437 void SWindow::SetStereoMode(StereoMode stereoMode, float eyesSpacing, float focalLength)
00438 {
00439
00440 if(currentStereoMode != stereoMode)
00441 {
00442 O3StereoManager->shutdown();
00443 currentStereoMode = SWindow::SO3_NONE_STEREO;
00444 }
00445
00446 switch (stereoMode)
00447 {
00448 case SWindow::SO3_ANAGLYPH_RC_STEREO:
00449 O3StereoManager->init(O3Window->getViewport(0), NULL, Ogre::StereoManager::SM_ANAGLYPH_RC);
00450 break;
00451 case SWindow::SO3_ANAGLYPH_YB_STEREO:
00452 O3StereoManager->init(O3Window->getViewport(0), NULL, Ogre::StereoManager::SM_ANAGLYPH_YB);
00453 break;
00454 case SWindow::SO3_DUALOUTPUT_STEREO:
00455 O3StereoManager->init(O3Window->getViewport(0), NULL, Ogre::StereoManager::SM_DUALOUTPUT);
00456 break;
00457 case SWindow::SO3_INTERLACED_CB_STEREO:
00458 O3StereoManager->init(O3Window->getViewport(0), NULL, Ogre::StereoManager::SM_INTERLACED_CB);
00459 break;
00460 case SWindow::SO3_INTERLACED_H_STEREO:
00461 O3StereoManager->init(O3Window->getViewport(0), NULL, Ogre::StereoManager::SM_INTERLACED_H);
00462 break;
00463 case SWindow::SO3_INTERLACED_V_STEREO:
00464 O3StereoManager->init(O3Window->getViewport(0), NULL, Ogre::StereoManager::SM_INTERLACED_V);
00465 break;
00466 };
00467
00468 if (stereoMode != SWindow::SO3_NONE_STEREO)
00469 {
00470 SetStereoEyesSpacing(eyesSpacing);
00471 SetStereoFocalLength(focalLength);
00472 }
00473 currentStereoMode = stereoMode;
00474 }
00475
00476 SWindow::StereoMode SWindow::GetStereoMode()
00477 {
00478 return currentStereoMode;
00479 }
00480
00481 float SWindow::GetStereoEyesSpacing()
00482 {
00483 return O3StereoManager->getEyesSpacing();
00484 }
00485
00486 void SWindow::SetStereoEyesSpacing(float eyesSpacing)
00487 {
00488 O3StereoManager->setEyesSpacing(eyesSpacing);
00489 }
00490
00491 float SWindow::GetStereoFocalLength()
00492 {
00493 float returnValue;
00494 if (O3StereoManager->isFocalLengthInfinite())
00495 returnValue = -1.0f;
00496 else
00497 returnValue = O3StereoManager->getFocalLength();
00498
00499 return returnValue;
00500 }
00501
00502 void SWindow::SetStereoFocalLength(float focalLength)
00503 {
00504 if(focalLength == -1.0f)
00505 {
00506 O3StereoManager->setFocalLengthInfinite(true);
00507 }
00508 else
00509 {
00510 O3StereoManager->setFocalLengthInfinite(false);
00511 O3StereoManager->setFocalLength(focalLength);
00512 }
00513 }
00514
00515 SRaycastResult SWindow::RayCast(int pixelsX, int pixelsY)
00516 {
00517 SRaycastResult raycastResults;
00518
00519
00520 SViewPort* resultViewport = GetViewport(pixelsX, pixelsY);
00521 if (resultViewport != 0)
00522 {
00523
00524 raycastResults = resultViewport->RayCast(pixelsX, pixelsY, subEntitySelector);
00525 }
00526
00527 lastRaycast = raycastResults;
00528 return raycastResults;
00529 }
00530
00531 SRaycastResult& SWindow::GetLastRayCast()
00532 {
00533
00534 bool lastLogstate = SRoot::getSingleton().GetLogEnable();
00535 SRoot::getSingleton().SetLogEnable(false);
00536
00537 try
00538 {
00539 if(lastRaycast.sceneName != "")
00540 {
00541 Ogre::SceneManager* sceneManager = Ogre::Root::getSingleton().getSceneManager(lastRaycast.sceneName);
00542 Ogre::Entity* entity = sceneManager->getEntity(lastRaycast.entityName);
00543
00544 }
00545 else
00546 {
00547
00548 lastRaycast = SRaycastResult();
00549 }
00550 }
00551 catch(Ogre::Exception& e)
00552 {
00553 SRoot::getSingleton().SetLogEnable(lastLogstate);
00554
00555
00556 lastRaycast = SRaycastResult();
00557
00558
00559 if(e.getNumber() != Ogre::Exception::ERR_ITEM_NOT_FOUND)
00560 {
00561 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_CRITICAL, true);
00562 throw e;
00563 }
00564 }
00565
00566
00567 SRoot::getSingleton().SetLogEnable(lastLogstate);
00568
00569 return lastRaycast;
00570 }
00571
00572 }