ViSP
vpAROgre.cpp
1 /****************************************************************************
2  *
3  * $Id: vpAROgre.cpp 5234 2015-01-30 13:51:02Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Augmented Reality viewer using Ogre3D.
36  *
37  * Authors:
38  * Bertrand Delabarre
39  *
40  *****************************************************************************/
41 
52 #include "visp/vpConfig.h"
53 
54 #ifdef VISP_HAVE_OGRE
55 
56 #include "visp/vpAROgre.h"
57 #include "visp/vpIoTools.h"
58 
59 
76  unsigned int width, unsigned int height,
77  const char *resourcePath, const char *pluginsPath)
78  : name("ViSP - Augmented Reality"),mRoot(0), mCamera(0), mSceneMgr(0), mWindow(0),
79  mResourcePath(resourcePath), mPluginsPath(pluginsPath),
80 #ifdef VISP_HAVE_OIS
81  mInputManager(0), mKeyboard(0),
82 #endif
83  keepOn(true), // When created no reason to stop displaying
84  mImageRGBA(), mImage(), mPixelBuffer(NULL), mBackground(NULL), mBackgroundHeight(0),
85  mBackgroundWidth(0), mWindowHeight(height), mWindowWidth(width), windowHidden(false),
86  mNearClipping(0.001), mFarClipping(200), mcam(cam), mshowConfigDialog(true),
87  mOptionnalResourceLocation()
88 {
89 }
90 
120  bool
121 #ifdef VISP_HAVE_OIS
122  bufferedKeys
123 #endif
124  ,bool hidden
125  )
126 {
129 
130  init(
131 #ifdef VISP_HAVE_OIS
132  bufferedKeys,
133 #else
134  false,
135 #endif
136  hidden
137  );
138  // Create the background image which will come from the grabber
139  createBackground(I);
140 }
141 
171  bool
172 #ifdef VISP_HAVE_OIS
173  bufferedKeys
174 #endif
175  ,bool hidden
176  )
177 {
180 
181  init(
182 #ifdef VISP_HAVE_OIS
183  bufferedKeys,
184 #else
185  false,
186 #endif
187  hidden
188  );
189  // Create the background image which will come from the grabber
190  createBackground(I);
191 }
192 
217 void vpAROgre::init(bool
218 #ifdef VISP_HAVE_OIS
219  bufferedKeys
220 #endif
221  ,bool hidden
222  )
223 {
224  // Create the root
225  // mPluginsPath may contain more than one folder location separated by ";"
226  bool pluginsFileExists = false;
227  std::string pluginFile;
228  std::vector<std::string> plugingsPaths = vpIoTools::splitChain(std::string(mPluginsPath), std::string(";"));
229  for (size_t i=0; i<plugingsPaths.size(); i++) {
230 #if defined(NDEBUG) || !defined(_WIN32)
231  pluginFile = plugingsPaths[i]+"/plugins.cfg";
232 #else
233  pluginFile = plugingsPaths[i]+"/plugins_d.cfg";
234 #endif
235 
236  if(vpIoTools::checkFilename(pluginFile)) {
237  pluginsFileExists = true;
238  break;
239  }
240  }
241  if (! pluginsFileExists) {
242  std::string errorMsg = std::string("Error: the requested plugins file \"")
243 #if defined(NDEBUG) || !defined(_WIN32)
244  + std::string("plugins.cfg")
245 #else
246  + std::string("plugins_d.cfg")
247 #endif
248  + std::string("\" doesn't exist in ")
249  + std::string(mPluginsPath);
250  std::cout << errorMsg << std::endl;
251 
252  throw (vpException(vpException::ioError, errorMsg));
253  }
254  std::cout << "######################### Load plugin file: " << pluginFile << std::endl;
255 
256  if(Ogre::Root::getSingletonPtr() == NULL)
257  mRoot = new Ogre::Root(pluginFile, "ogre.cfg", "Ogre.log");
258  else
259  mRoot = Ogre::Root::getSingletonPtr();
260 
261  // Load resource paths from config file
262 
263  // File format is:
264  // [ResourceGroupName]
265  // ArchiveType=Path
266  // .. repeat
267  // For example:
268  // [General]
269  // FileSystem=media/
270  // Zip=packages/level1.zip
271 
272  // mResourcePath may contain more than one folder location separated by ";"
273  bool resourcesFileExists = false;
274  std::string resourceFile;
275  std::vector<std::string> resourcesPaths = vpIoTools::splitChain(std::string(mResourcePath), std::string(";"));
276  for (size_t i=0; i<resourcesPaths.size(); i++) {
277  resourceFile = resourcesPaths[i]+"/resources.cfg";
278  if(vpIoTools::checkFilename(resourceFile)) {
279  resourcesFileExists = true;
280  break;
281  }
282  }
283  if (! resourcesFileExists) {
284  std::string errorMsg = std::string("Error: the requested resource file \"resources.cfg\"")
285  + std::string("doesn't exist in ")
286  + std::string(mResourcePath);
287 
288  std::cout << errorMsg << std::endl;
289 
290  throw (vpException(vpException::ioError, errorMsg));
291  }
292  std::cout << "######################### Load resource file: " << resourceFile << std::endl;
293  Ogre::ConfigFile cf;
294  cf.load(resourceFile);
295 
296  // Go through all sections & settings in the file
297  Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
298 
299  Ogre::String secName, typeName, archName;
300  while (seci.hasMoreElements())
301  {
302  secName = seci.peekNextKey();
303  Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
304  Ogre::ConfigFile::SettingsMultiMap::iterator i;
305  for (i = settings->begin(); i != settings->end(); ++i)
306  {
307  typeName = i->first;
308  archName = i->second;
309  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
310  archName, typeName, secName);
311  }
312  }
313  std::cout << "##################### add resources" << std::endl;
314  //Add optionnal resources (given by the user).
315  for(std::list<std::string>::const_iterator iter = mOptionnalResourceLocation.begin(); iter != mOptionnalResourceLocation.end(); ++iter){
316  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(*iter, "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
317  }
318 
319  // Create the window
320  bool canInit = true;
321  if(mshowConfigDialog){
322  mRoot->restoreConfig();
323  if(!mRoot->showConfigDialog())
324  canInit = false;
325  }
326  else{
327  if(!mRoot->restoreConfig())
328  canInit = false;
329  }
330 
331  if(!mRoot->isInitialised()){
332  if(!canInit){ //We set the default renderer system
333  const Ogre::RenderSystemList& lRenderSystemList = mRoot->getAvailableRenderers();
334  if( lRenderSystemList.size() == 0 )
335  throw "ConfigDialog aborted"; // Exit the application on cancel
336 
337  Ogre::RenderSystem *lRenderSystem = lRenderSystemList.at(0);
338  std::cout << "Using " << lRenderSystem->getName() << " as renderer." << std::endl;
339  mRoot->setRenderSystem(lRenderSystem);
340  }
341 
342  mRoot->initialise(false);
343  }
344 
345  bool fullscreen = false;
346  Ogre::NameValuePairList misc;
347  Ogre::ConfigOptionMap config = mRoot->getRenderSystem()->getConfigOptions();
348  Ogre::ConfigOptionMap::const_iterator it = config.begin();
349 
350  while( it != config.end() ){
351  Ogre::String leftconf = (*it).first;
352  Ogre::String rightconf = (*it).second.currentValue;
353 
354  if(leftconf == "Video Mode"){
355  if(canInit) {
356  int ret = sscanf(rightconf.c_str(), "%d %*s %d", &mWindowWidth, &mWindowHeight);
357  if (ret == 0)
358  std::cout << "Cannot read Ogre video mode" << std::endl;
359  }
360  else{
361  if(mWindowWidth == 0 && mWindowHeight == 0){
364  }
365  }
366  }
367  else if( leftconf == "Full Screen" ){
368  if(canInit){
369  if(rightconf == "Yes") fullscreen = true;
370  }
371  }
372  else
373  misc[leftconf] = rightconf;
374 
375  it++;
376  }
377 
378  // With Ogre version >= 1.8.1 we hide the window
379  if( hidden ){
380 #if ( OGRE_VERSION >= (1 << 16 | 8 << 8 | 1) )
381  misc["hidden"] = "true";
382  windowHidden = true;
383 #endif
384  }
385  mWindow = mRoot->createRenderWindow(name, mWindowWidth, mWindowHeight, fullscreen, &misc);
386 
387  // Initialise resources
388  Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
389  //-----------------------------------------------------
390  // 4 Create the SceneManager
391  //
392  // ST_GENERIC = octree
393  // ST_EXTERIOR_CLOSE = simple terrain
394  // ST_EXTERIOR_FAR = nature terrain (depreciated)
395  // ST_EXTERIOR_REAL_FAR = paging landscape
396  // ST_INTERIOR = Quake3 BSP
397  //-----------------------------------------------------
398 
399  mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
400 
401  // Create the camera
402  createCamera();
403 
404  // Create a viewport
405  Ogre::Viewport* viewPort = mWindow->addViewport(mCamera);
406 // Ogre::Viewport* viewPort = mCamera->getViewport();
407  viewPort->setClearEveryFrame(true);
408  // Set the projection parameters to match the camera intrinsic parameters
410 
411  // Create the 3D scene
412  createScene();
413 
414  // Initialise and register event handlers
415  mRoot->addFrameListener(this);
416 
417  // Register as a Window listener
418  Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
419 
420 #ifdef VISP_HAVE_OIS
421  // Initialise OIS
422  Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
423  OIS::ParamList pl;
424 
425  size_t windowHnd = 0;
426  std::ostringstream windowHndStr;
427  // Initialise window
428  mWindow->getCustomAttribute("WINDOW", &windowHnd);
429  windowHndStr << windowHnd;
430  pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
431  // Let the user use the keyboard elsewhere
432 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
433  pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
434 #endif
435 
436  mInputManager = OIS::InputManager::createInputSystem( pl );
437 
438  //Create all devices
439  // Here we only consider the keyboard input
440  mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));
441  if ( !bufferedKeys ) mKeyboard->setEventCallback ( this);
442 #endif
443 
444  // Initialise a render to texture to be able to retrieve a screenshot
445  Ogre::TexturePtr Texture = Ogre::TextureManager::getSingleton().createManual("rtf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,Ogre::TEX_TYPE_2D,
446  mWindow->getWidth(),mWindow->getHeight(), 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET);
447 
448 
449 
450 // Ogre::TexturePtr Texture = Ogre::TextureManager::getSingleton().createManual("rtf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,Ogre::TEX_TYPE_2D,
451 // 640,480, 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET);
452  Ogre::RenderTexture* RTarget = Texture->getBuffer()->getRenderTarget();
453  /*Ogre::Viewport* Viewport =*/ RTarget->addViewport(mCamera);
454  RTarget->getViewport(0)->setClearEveryFrame(true);
455  RTarget->getViewport(0)->setOverlaysEnabled(false);
456 }
457 
462 {
463  // Destroy 3D scene
464  destroyScene();
465  // Close OIS
466  closeOIS();
467 
468  if ( mWindow) {
469  Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
471  }
472  // Delete root
473  if (mRoot) delete mRoot;
474 }
475 
481 bool vpAROgre::stopTest(const Ogre::FrameEvent& evt)
482 {
483  // Always keep this part
484  if(keepOn){
485  return updateScene(evt);
486  }
487  else
488  return keepOn;
489 }
490 
500 bool vpAROgre::frameStarted(const Ogre::FrameEvent& evt)
501 {
502  // custom method telling what to do at the beginning of each frame
503  bool result = customframeStarted(evt);
504 
505  // Listen to the window
506  Ogre::WindowEventUtilities::messagePump();
507  processInputEvent(evt);
508 
509  // See if we have to stop rendering
510  if(result) return stopTest(evt);
511  else return result;
512 }
513 
514 
521 bool vpAROgre::frameEnded(const Ogre::FrameEvent& evt)
522 {
523  // custom method telling what to do at the end of each frame
524  bool result = customframeEnded(evt);
525 
526  // See if we have to stop rendering
527  if(result) return stopTest(evt);
528  else return result;
529 }
530 
539 bool vpAROgre::customframeStarted(const Ogre::FrameEvent& /*evt*/)
540 {
541  // See if window was closed
542  if(mWindow->isClosed()) return false;
543 
544 #ifdef VISP_HAVE_OIS
545  // Get keyboard input
546  mKeyboard->capture();
547  if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
548  return false;
549 #endif
550  return true;
551 }
552 
553 
559 bool vpAROgre::customframeEnded(const Ogre::FrameEvent& /*evt*/){return true;}
560 
571 void vpAROgre::windowClosed(Ogre::RenderWindow* rw)
572 {
573  //Only close for window that created OIS (the main window in these demos)
574  if( rw == mWindow ) closeOIS();
575 }
576 
583  const vpHomogeneousMatrix &cMw)
584 {
585  // Update the background to match the situation
587 
588  // Update the camera parameters to match the grabbed image
590 
591  // Display on Ogre Window
592  return mRoot->renderOneFrame();
593 }
594 
601  const vpHomogeneousMatrix &cMw)
602 {
603  // Update the background to match the situation
605 
606  // Update the camera parameters to match the grabbed image
608 
609  // Display on Ogre Window
610  return mRoot->renderOneFrame();
611 }
612 
619  const vpHomogeneousMatrix &cMw)
620 {
621  // Display on Ogre Window
622  if(renderOneFrame(I,cMw)){
623  mWindow->update();
624  keepOn = true;
625  }
626  else
627  keepOn = false;
628 }
629 
636 {
637  // Display on Ogre Window
638  if(renderOneFrame(I,cMw)){
639  mWindow->update();
640  keepOn = true;
641  }
642  else
643  keepOn = false;
644 }
645 
651 {
652  return keepOn;
653 }
654 
659 {
660  mcam = cameraP;
661 }
662 
668 void vpAROgre::load(const std::string &name, const std::string &model)
669 {
670  Ogre::Entity *newEntity = mSceneMgr->createEntity(name, model);
671  Ogre::SceneNode *newNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(name);
672  newNode->attachObject(newEntity);
673 }
674 
681 void vpAROgre::setPosition(const std::string &name,
682  const vpTranslationVector &wTo)
683 {
684  // Reset the position
685  Ogre::SceneNode *node = mSceneMgr->getSceneNode(name);
686  node->setPosition((Ogre::Real)wTo[0], (Ogre::Real)wTo[1], (Ogre::Real)wTo[2]);
687 }
688 
694 vpTranslationVector vpAROgre::getPosition(const std::string &name)const
695 {
696  Ogre::Vector3 translation = mSceneMgr->getSceneNode(name)->getPosition();
697  return vpTranslationVector((Ogre::Real)translation[0], (Ogre::Real)translation[1], (Ogre::Real)translation[2]);
698 }
699 
705 void vpAROgre::setRotation(const std::string &name, const vpRotationMatrix &wRo)
706 {
707  // Get the node in its original position
708  mSceneMgr->getSceneNode(name)->resetOrientation();
709  // Apply the new rotation
710  Ogre::Matrix3 rotationOgre
711  = Ogre::Matrix3( (Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
712  (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
713  (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
714  Ogre::Quaternion q(rotationOgre);
715  mSceneMgr->getSceneNode(name)->rotate(q);
716 }
717 
723 void vpAROgre::addRotation(const std::string &name,
724  const vpRotationMatrix &wRo)
725 {
726  // Apply the new rotation
727  Ogre::Matrix3 rotationOgre
728  = Ogre::Matrix3( (Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
729  (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
730  (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
731  Ogre::Quaternion q(rotationOgre);
732  mSceneMgr->getSceneNode(name)->rotate(q);
733 
734 
735 }
736 
745 void vpAROgre::setPosition(const std::string &name,
746  const vpHomogeneousMatrix &wMo)
747 {
748  // Extract the position and orientation data
749  vpRotationMatrix rotations;
750  vpTranslationVector translation;
751  wMo.extract(rotations);
752  wMo.extract(translation);
753  // Apply them to the node
754  setPosition(name, translation);
755  setRotation(name, rotations);
756 }
757 
763 void vpAROgre::setVisibility(const std::string &name, bool isVisible)
764 {
765  mSceneMgr->getSceneNode(name)->setVisible(isVisible);
766 }
767 
775 void vpAROgre::setScale(const std::string &name, const float factorx, const float factory, const float factorz)
776 {
777  // Reset the scale to its original value
778  mSceneMgr->getSceneNode(name)->scale(Ogre::Vector3(1,1,1)/mSceneMgr->getSceneNode(name)->getScale());
779  // Apply the new scale
780  mSceneMgr->getSceneNode(name)->scale(Ogre::Vector3(factorx, factory, factorz));
781 }
782 
787 {
788  mCamera = mSceneMgr->createCamera("Camera");
789 }
790 
796 void vpAROgre::createBackground(vpImage<unsigned char> & /* I */)
797 {
798  // Create a rectangle to show the incoming images from the camera
799  mBackground = new Ogre::Rectangle2D(true); // true = textured
800  mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
801  mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0*Ogre::Vector3::UNIT_SCALE, 100000.0*Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
802 
803  // Texture options
804  Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
805  Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
806 
807  // Dynamic texture
808  // If we are using opengl we can boost a little bit performances with a dynamic texture
809  if(mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
810  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
811  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
812  Ogre::TEX_TYPE_2D,
813  mBackgroundWidth,//width
814  mBackgroundHeight,//height
815  0, // num of mip maps
816  Ogre::PF_BYTE_L,
817  Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
818  }
819  else{
820  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
821  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
822  Ogre::TEX_TYPE_2D,
823  mBackgroundWidth,//width
824  mBackgroundHeight,//height
825  0, // num of mip maps
826  Ogre::PF_BYTE_L,
827  Ogre::TU_DEFAULT);
828  }
829 
830  // Pointer to the dynamic texture
831  Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
832 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
833 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
834 //#else
835 // ;
836 //#endif
837  mPixelBuffer = dynTexPtr->getBuffer();
838 
839  // Material to apply the texture to the background
840  Ogre::MaterialPtr Backgroundmaterial
841  = Ogre::MaterialManager::getSingleton().create("BackgroundMaterial",
842  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
843 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
844 // .dynamicCast<Ogre::Material>();
845 //#else
846 // ;
847 //#endif
848  Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
849  Backgroundtechnique->createPass();
850  Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
851  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
852  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
853  Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
854  mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
855  mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
856 
857  // Add the background to the Scene Graph so it will be rendered
858  Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
859  BackgroundNode->attachObject(mBackground);
860 }
861 
867 void vpAROgre::createBackground(vpImage<vpRGBa> & /* I */)
868 {
869  // Create a rectangle to show the incoming images from the camera
870  mBackground = new Ogre::Rectangle2D(true); // true = textured
871  mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
872  mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0*Ogre::Vector3::UNIT_SCALE, 100000.0*Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
873 
874  // Texture options
875  Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
876  Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
877 
878  // Dynamic texture
879  // If we are using opengl we can boost a little bit performances with a dynamic texture
880  if(mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
881  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
882  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
883  Ogre::TEX_TYPE_2D,
884  mBackgroundWidth,//width
885  mBackgroundHeight,//height
886  0, // num of mip maps
887  //Ogre::PF_BYTE_RGBA,
888  Ogre::PF_BYTE_BGRA,
889  Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
890  }
891  else{ // As that texture does not seem to work properly with direct3D we use a default texture
892  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
893  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
894  Ogre::TEX_TYPE_2D,
895  mBackgroundWidth,//width
896  mBackgroundHeight,//height
897  0, // num of mip maps
898  //Ogre::PF_BYTE_RGBA,
899  Ogre::PF_BYTE_BGRA,
900  Ogre::TU_DEFAULT);
901  }
902 
903 
904  // Pointer to the dynamic texture
905  Ogre::TexturePtr dynTexPtr =
906  Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
907 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
908 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
909 //#else
910 // ;
911 //#endif
912 
913  // Get the pixel buffer
914  mPixelBuffer = dynTexPtr->getBuffer();
915 
916  // Material to apply the texture to the background
917  Ogre::MaterialPtr Backgroundmaterial
918  = Ogre::MaterialManager::getSingleton().create("BackgroundMaterial",
919  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
920 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
921 // .dynamicCast<Ogre::Material>();
922 //#else
923 // ;
924 //#endif
925  Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
926  Backgroundtechnique->createPass();
927  Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
928  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
929  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
930  Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
931  mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
932  mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
933 
934  // Add the background to the Scene Graph so it will be rendered
935  Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
936  BackgroundNode->attachObject(mBackground);
937 }
938 
947 {
948 #ifdef VISP_HAVE_OIS
949  if( mInputManager )
950  {
951  mInputManager->destroyInputObject( mKeyboard );
952 
953  OIS::InputManager::destroyInputSystem(mInputManager);
954  mInputManager = 0;
955  }
956 #endif
957 }
958 
962 // Note: equation taken from:
963 // http://strawlab.org/2011/11/05/augmented-reality-with-OpenGL/
965 {
966  if(mCamera != 0){
967  Ogre::Real f,n,f_m_n,f_p_n,px,py,u0,v0;
968  f = (Ogre::Real)(mFarClipping); // Far clip distance
969  n = (Ogre::Real)(mNearClipping); // Near clip distance
970  f_m_n = (Ogre::Real)(f-n);
971  f_p_n = (Ogre::Real)(f+n);
972  px = (Ogre::Real)mcam.get_px();
973  py = (Ogre::Real)mcam.get_py();
974  u0 = (Ogre::Real)mcam.get_u0();
975  v0 = (Ogre::Real)mcam.get_v0();
976  Ogre::Matrix4 Projection
977  = Ogre::Matrix4( (Ogre::Real)(2.0*px/mBackgroundWidth), 0, (Ogre::Real)(1.0 - 2.0*(u0/mBackgroundWidth)), 0,
978  0, (Ogre::Real)(2.0*py/mBackgroundHeight), (Ogre::Real)(-1.0 + 2.0*(v0/mBackgroundHeight)),0,
979  0, 0, (Ogre::Real)(-1.0*f_p_n/f_m_n), (Ogre::Real)(-2.0*f*n/f_m_n),
980  0, 0, -1.0, 0);
981  mCamera->setCustomProjectionMatrix(true, Projection);
982  }
983 }
984 
989 {
990  // Inspired from Ogre wiki : http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
991  // Lock the pixel buffer and get a pixel box. HBL_DISCARD is to use for best
992  // performance than HBL_NORMAL
993  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
994  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
995  // Buffer data
996  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
997  // Fill in the data in the grey level texture
998  memcpy(pDest, I.bitmap, mBackgroundHeight*mBackgroundWidth);
999 
1000  // Unlock the pixel buffer
1001  mPixelBuffer->unlock();
1002 }
1003 
1008 {
1009  // Inspired from Ogre wiki : http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
1010  // Lock the pixel buffer and get a pixel box. HBL_DISCARD is to use for best
1011  // performance than HBL_NORMAL
1012  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
1013  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
1014  // Buffer data
1015  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
1016  // Fill in the data in the grey level texture
1017 #if 1 // if texture in BGRa format
1018  for(unsigned int i=0; i<mBackgroundHeight; i++){
1019  for(unsigned int j=0; j<mBackgroundWidth; j++){
1020  // Color Image
1021 // *pDest++=I[i][mBackgroundWidth-j].B; // Blue component
1022 // *pDest++=I[i][mBackgroundWidth-j].G; // Green component
1023 // *pDest++=I[i][mBackgroundWidth-j].R; // Red component
1024 
1025  *pDest++=I[i][j].B; // Blue component
1026  *pDest++=I[i][j].G; // Green component
1027  *pDest++=I[i][j].R; // Red component
1028 
1029  *pDest++ = 255; // Alpha component
1030  }
1031  }
1032 #else // if texture in RGBa format which is the format of the input image
1033  memcpy(pDest, I.bitmap, mBackgroundHeight*mBackgroundWidth*sizeof(vpRGBa));
1034 #endif
1035 
1036  // Unlock the pixel buffer
1037  mPixelBuffer->unlock();
1038 }
1039 
1044 {
1045  // The matrix is given to Ogre with some changes to fit with the world projection
1046  Ogre::Matrix4 ModelView
1047 // = Ogre::Matrix4( (Ogre::Real)-cMo[0][0], (Ogre::Real)-cMo[0][1], (Ogre::Real)-cMo[0][2], (Ogre::Real)-cMo[0][3],
1048  = Ogre::Matrix4( (Ogre::Real)cMw[0][0], (Ogre::Real)cMw[0][1], (Ogre::Real)cMw[0][2], (Ogre::Real)cMw[0][3],
1049  (Ogre::Real)-cMw[1][0], (Ogre::Real)-cMw[1][1], (Ogre::Real)-cMw[1][2], (Ogre::Real)-cMw[1][3],
1050  (Ogre::Real)-cMw[2][0], (Ogre::Real)-cMw[2][1], (Ogre::Real)-cMw[2][2], (Ogre::Real)-cMw[2][3],
1051  (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)1);
1052  mCamera->setCustomViewMatrix(true, ModelView);
1053 }
1054 
1062 {
1064  Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("rtf");
1065 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
1066 // .dynamicCast<Ogre::Texture>();
1067 //#else
1068 // ;
1069 //#endif
1070  Ogre::RenderTexture* RTarget = dynTexPtr->getBuffer()->getRenderTarget();
1071  mWindow->update();
1072  RTarget->update();
1073  if(I.getHeight() != mWindow->getHeight() || I.getWidth() != mWindow->getWidth()){
1074  I.resize(mWindow->getHeight(), mWindow->getWidth());
1075  }
1076  Ogre::HardwarePixelBufferSharedPtr mPixelBuffer = dynTexPtr->getBuffer();
1077  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
1078  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
1079  dynTexPtr->getBuffer()->blitToMemory(pixelBox);
1080  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
1081 #if 1 // if texture in BGRa format
1082  for(unsigned int i=0; i<I.getHeight(); i++){
1083  for(unsigned int j=0; j<I.getWidth(); j++){
1084  // Color Image
1085  I[i][j].B = *pDest++; // Blue component
1086  I[i][j].G = *pDest++; // Green component
1087  I[i][j].R = *pDest++; // Red component
1088  I[i][j].A = *pDest++; // Alpha component
1089  }
1090  }
1091 #else // if texture in RGBa format which is the format of the input image
1092  memcpy(I.bitmap, pDest, I.getHeight()*I.getWidth()*sizeof(vpRGBa));
1093 #endif
1094 
1095  // Unlock the pixel buffer
1096  mPixelBuffer->unlock();
1097 
1098 }
1099 
1100 
1101 #endif
1102 
virtual void updateBackgroundTexture(const vpImage< unsigned char > &I)
Definition: vpAROgre.cpp:988
bool keepOn
Definition: vpAROgre.h:373
bool mshowConfigDialog
Definition: vpAROgre.h:389
double get_u0() const
vpTranslationVector getPosition(const std::string &name) const
Definition: vpAROgre.cpp:694
Ogre::String name
Definition: vpAROgre.h:356
void setRotation(const std::string &name, const vpRotationMatrix &wRo)
Definition: vpAROgre.cpp:705
unsigned int getWidth() const
Definition: vpImage.h:161
unsigned int mWindowWidth
Definition: vpAROgre.h:381
Ogre::String mPluginsPath
Definition: vpAROgre.h:364
unsigned int mBackgroundWidth
Definition: vpAROgre.h:379
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
virtual bool customframeEnded(const Ogre::FrameEvent &evt)
Definition: vpAROgre.cpp:559
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
virtual bool destroyScene(void)
Definition: vpAROgre.h:324
Ogre::String mResourcePath
Definition: vpAROgre.h:363
error that can be emited by ViSP classes.
Definition: vpException.h:76
virtual void createCamera(void)
Definition: vpAROgre.cpp:786
void addRotation(const std::string &name, const vpRotationMatrix &wRo)
Definition: vpAROgre.cpp:723
vpAROgre(const vpCameraParameters &cam=vpCameraParameters(), unsigned int width=0, unsigned int height=0, const char *resourcePath=VISP_HAVE_OGRE_RESOURCES_PATH, const char *pluginsPath=VISP_HAVE_OGRE_PLUGINS_PATH)
Definition: vpAROgre.cpp:75
OIS::Keyboard * mKeyboard
Definition: vpAROgre.h:369
double get_py() const
bool renderOneFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:582
bool continueRendering(void)
Definition: vpAROgre.cpp:650
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:618
Class that defines a RGB 32 bits structure.
Definition: vpRGBa.h:68
Ogre::RenderWindow * mWindow
Definition: vpAROgre.h:362
OIS::InputManager * mInputManager
Definition: vpAROgre.h:368
The vpRotationMatrix considers the particular case of a rotation matrix.
virtual void updateCameraParameters(const vpHomogeneousMatrix &cMo)
Definition: vpAROgre.cpp:1043
static bool checkFilename(const char *filename)
Definition: vpIoTools.cpp:465
double get_v0() const
virtual void init(vpImage< unsigned char > &I, bool bufferedKeys=false, bool hidden=false)
Definition: vpAROgre.cpp:119
vpCameraParameters mcam
Definition: vpAROgre.h:387
virtual bool processInputEvent(const Ogre::FrameEvent &)
Definition: vpAROgre.h:317
void setCameraParameters(const vpCameraParameters &cameraP)
Definition: vpAROgre.cpp:658
virtual ~vpAROgre(void)
Definition: vpAROgre.cpp:461
Ogre::Camera * mCamera
Definition: vpAROgre.h:360
Generic class defining intrinsic camera parameters.
virtual void closeOIS(void)
Definition: vpAROgre.cpp:946
void setVisibility(const std::string &name, bool isVisible)
Definition: vpAROgre.cpp:763
virtual bool updateScene(const Ogre::FrameEvent &)
Definition: vpAROgre.h:310
virtual void windowClosed(Ogre::RenderWindow *rw)
Definition: vpAROgre.cpp:571
unsigned int mWindowHeight
Definition: vpAROgre.h:380
void resize(const unsigned int h, const unsigned int w)
set the size of the image without initializing it.
Definition: vpImage.h:536
bool windowHidden
Definition: vpAROgre.h:382
void extract(vpRotationMatrix &R) const
void getRenderingOutput(vpImage< vpRGBa > &I, const vpHomogeneousMatrix &cMo)
Definition: vpAROgre.cpp:1061
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1457
virtual bool customframeStarted(const Ogre::FrameEvent &evt)
Definition: vpAROgre.cpp:539
unsigned int mBackgroundHeight
Definition: vpAROgre.h:378
double get_px() const
virtual void updateCameraProjection(void)
Definition: vpAROgre.cpp:964
Ogre::Root * mRoot
Definition: vpAROgre.h:359
double mFarClipping
Definition: vpAROgre.h:386
Ogre::HardwarePixelBufferSharedPtr mPixelBuffer
Definition: vpAROgre.h:376
Ogre::Rectangle2D * mBackground
Definition: vpAROgre.h:377
virtual void createScene(void)
Definition: vpAROgre.h:301
Ogre::SceneManager * mSceneMgr
Definition: vpAROgre.h:361
void setScale(const std::string &name, const float factorx, const float factory, const float factorz)
Definition: vpAROgre.cpp:775
unsigned int getHeight() const
Definition: vpImage.h:152
void setPosition(const std::string &name, const vpTranslationVector &wTo)
Definition: vpAROgre.cpp:681
double mNearClipping
Definition: vpAROgre.h:385
std::list< std::string > mOptionnalResourceLocation
Definition: vpAROgre.h:391
void load(const std::string &name, const std::string &model)
Definition: vpAROgre.cpp:668
Class that consider the case of a translation vector.