ViSP  2.10.0
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 #if defined(NDEBUG) || !defined(_WIN32)
226  std::string pluginFile = mPluginsPath+"/plugins.cfg";
227 #else
228  std::string pluginFile = mPluginsPath+"/plugins_d.cfg";
229 #endif
230  if(!vpIoTools::checkFilename(pluginFile)){
231  std::string errorMsg = "Error: the requested plugins file \""
232  + pluginFile + "\" doesn't exist.";
233  std::cout << errorMsg << std::endl;
234 
235  throw (vpException(vpException::ioError, errorMsg));
236  }
237  std::cout << "######################### Load plugin file: " << pluginFile << std::endl;
238 
239  if(Ogre::Root::getSingletonPtr() == NULL)
240  mRoot = new Ogre::Root(pluginFile, "ogre.cfg", "Ogre.log");
241  else
242  mRoot = Ogre::Root::getSingletonPtr();
243 
244  // Load resource paths from config file
245 
246  // File format is:
247  // [ResourceGroupName]
248  // ArchiveType=Path
249  // .. repeat
250  // For example:
251  // [General]
252  // FileSystem=media/
253  // Zip=packages/level1.zip
254  Ogre::ConfigFile cf;
255  std::string resourceFile = mResourcePath+"/resources.cfg";
256  if(!vpIoTools::checkFilename(resourceFile)){
257  std::string errorMsg = "Error: the requested resource file \""
258  + resourceFile + "\" doesn't exist.";
259  std::cout << errorMsg << std::endl;
260 
261  throw (vpException(vpException::ioError, errorMsg));
262  }
263  std::cout << "######################### Load resource file: " << resourceFile << std::endl;
264  cf.load(resourceFile);
265 
266  // Go through all sections & settings in the file
267  Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
268 
269  Ogre::String secName, typeName, archName;
270  while (seci.hasMoreElements())
271  {
272  secName = seci.peekNextKey();
273  Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
274  Ogre::ConfigFile::SettingsMultiMap::iterator i;
275  for (i = settings->begin(); i != settings->end(); ++i)
276  {
277  typeName = i->first;
278  archName = i->second;
279  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
280  archName, typeName, secName);
281  }
282  }
283  std::cout << "##################### add resources" << std::endl;
284  //Add optionnal resources (given by the user).
285  for(std::list<std::string>::const_iterator iter = mOptionnalResourceLocation.begin(); iter != mOptionnalResourceLocation.end(); ++iter){
286  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(*iter, "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
287  }
288 
289  // Create the window
290  bool canInit = true;
291  if(mshowConfigDialog){
292  mRoot->restoreConfig();
293  if(!mRoot->showConfigDialog())
294  canInit = false;
295  }
296  else{
297  if(!mRoot->restoreConfig())
298  canInit = false;
299  }
300 
301  if(!mRoot->isInitialised()){
302  if(!canInit){ //We set the default renderer system
303  const Ogre::RenderSystemList& lRenderSystemList = mRoot->getAvailableRenderers();
304  if( lRenderSystemList.size() == 0 )
305  throw "ConfigDialog aborted"; // Exit the application on cancel
306 
307  Ogre::RenderSystem *lRenderSystem = lRenderSystemList.at(0);
308  std::cout << "Using " << lRenderSystem->getName() << " as renderer." << std::endl;
309  mRoot->setRenderSystem(lRenderSystem);
310  }
311 
312  mRoot->initialise(false);
313  }
314 
315  bool fullscreen = false;
316  Ogre::NameValuePairList misc;
317  Ogre::ConfigOptionMap config = mRoot->getRenderSystem()->getConfigOptions();
318  Ogre::ConfigOptionMap::const_iterator it = config.begin();
319 
320  while( it != config.end() ){
321  Ogre::String leftconf = (*it).first;
322  Ogre::String rightconf = (*it).second.currentValue;
323 
324  if(leftconf == "Video Mode"){
325  if(canInit) {
326  int ret = sscanf(rightconf.c_str(), "%d %*s %d", &mWindowWidth, &mWindowHeight);
327  if (ret == 0)
328  std::cout << "Cannot read Ogre video mode" << std::endl;
329  }
330  else{
331  if(mWindowWidth == 0 && mWindowHeight == 0){
334  }
335  }
336  }
337  else if( leftconf == "Full Screen" ){
338  if(canInit){
339  if(rightconf == "Yes") fullscreen = true;
340  }
341  }
342  else
343  misc[leftconf] = rightconf;
344 
345  it++;
346  }
347 
348  // With Ogre version >= 1.8.1 we hide the window
349  if( hidden ){
350 #if ( OGRE_VERSION >= (1 << 16 | 8 << 8 | 1) )
351  misc["hidden"] = "true";
352  windowHidden = true;
353 #endif
354  }
355  mWindow = mRoot->createRenderWindow(name, mWindowWidth, mWindowHeight, fullscreen, &misc);
356 
357  // Initialise resources
358  Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
359  //-----------------------------------------------------
360  // 4 Create the SceneManager
361  //
362  // ST_GENERIC = octree
363  // ST_EXTERIOR_CLOSE = simple terrain
364  // ST_EXTERIOR_FAR = nature terrain (depreciated)
365  // ST_EXTERIOR_REAL_FAR = paging landscape
366  // ST_INTERIOR = Quake3 BSP
367  //-----------------------------------------------------
368 
369  mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
370 
371  // Create the camera
372  createCamera();
373 
374  // Create a viewport
375  Ogre::Viewport* viewPort = mWindow->addViewport(mCamera);
376 // Ogre::Viewport* viewPort = mCamera->getViewport();
377  viewPort->setClearEveryFrame(true);
378  // Set the projection parameters to match the camera intrinsic parameters
380 
381  // Create the 3D scene
382  createScene();
383 
384  // Initialise and register event handlers
385  mRoot->addFrameListener(this);
386 
387  // Register as a Window listener
388  Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
389 
390 #ifdef VISP_HAVE_OIS
391  // Initialise OIS
392  Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
393  OIS::ParamList pl;
394 
395  size_t windowHnd = 0;
396  std::ostringstream windowHndStr;
397  // Initialise window
398  mWindow->getCustomAttribute("WINDOW", &windowHnd);
399  windowHndStr << windowHnd;
400  pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
401  // Let the user use the keyboard elsewhere
402 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
403  pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
404 #endif
405 
406  mInputManager = OIS::InputManager::createInputSystem( pl );
407 
408  //Create all devices
409  // Here we only consider the keyboard input
410  mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));
411  if ( !bufferedKeys ) mKeyboard->setEventCallback ( this);
412 #endif
413 
414  // Initialise a render to texture to be able to retrieve a screenshot
415  Ogre::TexturePtr Texture = Ogre::TextureManager::getSingleton().createManual("rtf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,Ogre::TEX_TYPE_2D,
416  mWindow->getWidth(),mWindow->getHeight(), 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET);
417 
418 
419 
420 // Ogre::TexturePtr Texture = Ogre::TextureManager::getSingleton().createManual("rtf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,Ogre::TEX_TYPE_2D,
421 // 640,480, 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET);
422  Ogre::RenderTexture* RTarget = Texture->getBuffer()->getRenderTarget();
423  /*Ogre::Viewport* Viewport =*/ RTarget->addViewport(mCamera);
424  RTarget->getViewport(0)->setClearEveryFrame(true);
425  RTarget->getViewport(0)->setOverlaysEnabled(false);
426 }
427 
432 {
433  // Destroy 3D scene
434  destroyScene();
435  // Close OIS
436  closeOIS();
437 
438  if ( mWindow) {
439  Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
441  }
442  // Delete root
443  if (mRoot) delete mRoot;
444 }
445 
451 bool vpAROgre::stopTest(const Ogre::FrameEvent& evt)
452 {
453  // Always keep this part
454  if(keepOn){
455  return updateScene(evt);
456  }
457  else
458  return keepOn;
459 }
460 
470 bool vpAROgre::frameStarted(const Ogre::FrameEvent& evt)
471 {
472  // custom method telling what to do at the beginning of each frame
473  bool result = customframeStarted(evt);
474 
475  // Listen to the window
476  Ogre::WindowEventUtilities::messagePump();
477  processInputEvent(evt);
478 
479  // See if we have to stop rendering
480  if(result) return stopTest(evt);
481  else return result;
482 }
483 
484 
491 bool vpAROgre::frameEnded(const Ogre::FrameEvent& evt)
492 {
493  // custom method telling what to do at the end of each frame
494  bool result = customframeEnded(evt);
495 
496  // See if we have to stop rendering
497  if(result) return stopTest(evt);
498  else return result;
499 }
500 
509 bool vpAROgre::customframeStarted(const Ogre::FrameEvent& /*evt*/)
510 {
511  // See if window was closed
512  if(mWindow->isClosed()) return false;
513 
514 #ifdef VISP_HAVE_OIS
515  // Get keyboard input
516  mKeyboard->capture();
517  if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
518  return false;
519 #endif
520  return true;
521 }
522 
523 
529 bool vpAROgre::customframeEnded(const Ogre::FrameEvent& /*evt*/){return true;}
530 
541 void vpAROgre::windowClosed(Ogre::RenderWindow* rw)
542 {
543  //Only close for window that created OIS (the main window in these demos)
544  if( rw == mWindow ) closeOIS();
545 }
546 
553  const vpHomogeneousMatrix &cMw)
554 {
555  // Update the background to match the situation
557 
558  // Update the camera parameters to match the grabbed image
560 
561  // Display on Ogre Window
562  return mRoot->renderOneFrame();
563 }
564 
571  const vpHomogeneousMatrix &cMw)
572 {
573  // Update the background to match the situation
575 
576  // Update the camera parameters to match the grabbed image
578 
579  // Display on Ogre Window
580  return mRoot->renderOneFrame();
581 }
582 
589  const vpHomogeneousMatrix &cMw)
590 {
591  // Display on Ogre Window
592  if(renderOneFrame(I,cMw)){
593  mWindow->update();
594  keepOn = true;
595  }
596  else
597  keepOn = false;
598 }
599 
606 {
607  // Display on Ogre Window
608  if(renderOneFrame(I,cMw)){
609  mWindow->update();
610  keepOn = true;
611  }
612  else
613  keepOn = false;
614 }
615 
621 {
622  return keepOn;
623 }
624 
629 {
630  mcam = cameraP;
631 }
632 
638 void vpAROgre::load(const std::string &name, const std::string &model)
639 {
640  Ogre::Entity *newEntity = mSceneMgr->createEntity(name, model);
641  Ogre::SceneNode *newNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(name);
642  newNode->attachObject(newEntity);
643 }
644 
651 void vpAROgre::setPosition(const std::string &name,
652  const vpTranslationVector &wTo)
653 {
654  // Reset the position
655  Ogre::SceneNode *node = mSceneMgr->getSceneNode(name);
656  node->setPosition((Ogre::Real)wTo[0], (Ogre::Real)wTo[1], (Ogre::Real)wTo[2]);
657 }
658 
664 vpTranslationVector vpAROgre::getPosition(const std::string &name)const
665 {
666  Ogre::Vector3 translation = mSceneMgr->getSceneNode(name)->getPosition();
667  return vpTranslationVector((Ogre::Real)translation[0], (Ogre::Real)translation[1], (Ogre::Real)translation[2]);
668 }
669 
675 void vpAROgre::setRotation(const std::string &name, const vpRotationMatrix &wRo)
676 {
677  // Get the node in its original position
678  mSceneMgr->getSceneNode(name)->resetOrientation();
679  // Apply the new rotation
680  Ogre::Matrix3 rotationOgre
681  = Ogre::Matrix3( (Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
682  (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
683  (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
684  Ogre::Quaternion q(rotationOgre);
685  mSceneMgr->getSceneNode(name)->rotate(q);
686 }
687 
693 void vpAROgre::addRotation(const std::string &name,
694  const vpRotationMatrix &wRo)
695 {
696  // Apply the new rotation
697  Ogre::Matrix3 rotationOgre
698  = Ogre::Matrix3( (Ogre::Real)wRo[0][0], (Ogre::Real)wRo[0][1], (Ogre::Real)wRo[0][2],
699  (Ogre::Real)wRo[1][0], (Ogre::Real)wRo[1][1], (Ogre::Real)wRo[1][2],
700  (Ogre::Real)wRo[2][0], (Ogre::Real)wRo[2][1], (Ogre::Real)wRo[2][2]);
701  Ogre::Quaternion q(rotationOgre);
702  mSceneMgr->getSceneNode(name)->rotate(q);
703 
704 
705 }
706 
715 void vpAROgre::setPosition(const std::string &name,
716  const vpHomogeneousMatrix &wMo)
717 {
718  // Extract the position and orientation data
719  vpRotationMatrix rotations;
720  vpTranslationVector translation;
721  wMo.extract(rotations);
722  wMo.extract(translation);
723  // Apply them to the node
724  setPosition(name, translation);
725  setRotation(name, rotations);
726 }
727 
733 void vpAROgre::setVisibility(const std::string &name, bool isVisible)
734 {
735  mSceneMgr->getSceneNode(name)->setVisible(isVisible);
736 }
737 
745 void vpAROgre::setScale(const std::string &name, const float factorx, const float factory, const float factorz)
746 {
747  // Reset the scale to its original value
748  mSceneMgr->getSceneNode(name)->scale(Ogre::Vector3(1,1,1)/mSceneMgr->getSceneNode(name)->getScale());
749  // Apply the new scale
750  mSceneMgr->getSceneNode(name)->scale(Ogre::Vector3(factorx, factory, factorz));
751 }
752 
757 {
758  mCamera = mSceneMgr->createCamera("Camera");
759 }
760 
766 void vpAROgre::createBackground(vpImage<unsigned char> & /* I */)
767 {
768  // Create a rectangle to show the incoming images from the camera
769  mBackground = new Ogre::Rectangle2D(true); // true = textured
770  mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
771  mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0*Ogre::Vector3::UNIT_SCALE, 100000.0*Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
772 
773  // Texture options
774  Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
775  Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
776 
777  // Dynamic texture
778  // If we are using opengl we can boost a little bit performances with a dynamic texture
779  if(mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
780  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
781  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
782  Ogre::TEX_TYPE_2D,
783  mBackgroundWidth,//width
784  mBackgroundHeight,//height
785  0, // num of mip maps
786  Ogre::PF_BYTE_L,
787  Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
788  }
789  else{
790  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
791  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
792  Ogre::TEX_TYPE_2D,
793  mBackgroundWidth,//width
794  mBackgroundHeight,//height
795  0, // num of mip maps
796  Ogre::PF_BYTE_L,
797  Ogre::TU_DEFAULT);
798  }
799 
800  // Pointer to the dynamic texture
801  Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
802 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
803 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
804 //#else
805 // ;
806 //#endif
807  mPixelBuffer = dynTexPtr->getBuffer();
808 
809  // Material to apply the texture to the background
810  Ogre::MaterialPtr Backgroundmaterial
811  = Ogre::MaterialManager::getSingleton().create("BackgroundMaterial",
812  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
813 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
814 // .dynamicCast<Ogre::Material>();
815 //#else
816 // ;
817 //#endif
818  Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
819  Backgroundtechnique->createPass();
820  Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
821  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
822  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
823  Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
824  mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
825  mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
826 
827  // Add the background to the Scene Graph so it will be rendered
828  Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
829  BackgroundNode->attachObject(mBackground);
830 }
831 
837 void vpAROgre::createBackground(vpImage<vpRGBa> & /* I */)
838 {
839  // Create a rectangle to show the incoming images from the camera
840  mBackground = new Ogre::Rectangle2D(true); // true = textured
841  mBackground->setCorners(-1.0, 1.0, 1.0, -1.0); // Spread all over the window
842  mBackground->setBoundingBox(Ogre::AxisAlignedBox(-100000.0*Ogre::Vector3::UNIT_SCALE, 100000.0*Ogre::Vector3::UNIT_SCALE)); // To be shown everywhere
843 
844  // Texture options
845  Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_NONE);
846  Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
847 
848  // Dynamic texture
849  // If we are using opengl we can boost a little bit performances with a dynamic texture
850  if(mRoot->getRenderSystem()->getName() == "OpenGL Rendering Subsystem") {
851  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
852  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
853  Ogre::TEX_TYPE_2D,
854  mBackgroundWidth,//width
855  mBackgroundHeight,//height
856  0, // num of mip maps
857  //Ogre::PF_BYTE_RGBA,
858  Ogre::PF_BYTE_BGRA,
859  Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
860  }
861  else{ // As that texture does not seem to work properly with direct3D we use a default texture
862  Ogre::TextureManager::getSingleton().createManual("BackgroundTexture",
863  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
864  Ogre::TEX_TYPE_2D,
865  mBackgroundWidth,//width
866  mBackgroundHeight,//height
867  0, // num of mip maps
868  //Ogre::PF_BYTE_RGBA,
869  Ogre::PF_BYTE_BGRA,
870  Ogre::TU_DEFAULT);
871  }
872 
873 
874  // Pointer to the dynamic texture
875  Ogre::TexturePtr dynTexPtr =
876  Ogre::TextureManager::getSingleton().getByName("BackgroundTexture");
877 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
878 // .dynamicCast<Ogre::Texture>();// Get the pixel buffer
879 //#else
880 // ;
881 //#endif
882 
883  // Get the pixel buffer
884  mPixelBuffer = dynTexPtr->getBuffer();
885 
886  // Material to apply the texture to the background
887  Ogre::MaterialPtr Backgroundmaterial
888  = Ogre::MaterialManager::getSingleton().create("BackgroundMaterial",
889  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
890 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
891 // .dynamicCast<Ogre::Material>();
892 //#else
893 // ;
894 //#endif
895  Ogre::Technique *Backgroundtechnique = Backgroundmaterial->createTechnique();
896  Backgroundtechnique->createPass();
897  Backgroundmaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
898  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); // Background
899  Backgroundmaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); // Background
900  Backgroundmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTexture");
901  mBackground->setMaterial("BackgroundMaterial"); // Attach the material to the rectangle
902  mBackground->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND); // To be rendered in Background
903 
904  // Add the background to the Scene Graph so it will be rendered
905  Ogre::SceneNode *BackgroundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("BackgoundNode");
906  BackgroundNode->attachObject(mBackground);
907 }
908 
917 {
918 #ifdef VISP_HAVE_OIS
919  if( mInputManager )
920  {
921  mInputManager->destroyInputObject( mKeyboard );
922 
923  OIS::InputManager::destroyInputSystem(mInputManager);
924  mInputManager = 0;
925  }
926 #endif
927 }
928 
932 // Note: equation taken from:
933 // http://strawlab.org/2011/11/05/augmented-reality-with-OpenGL/
935 {
936  if(mCamera != 0){
937  Ogre::Real f,n,f_m_n,f_p_n,px,py,u0,v0;
938  f = (Ogre::Real)(mFarClipping); // Far clip distance
939  n = (Ogre::Real)(mNearClipping); // Near clip distance
940  f_m_n = (Ogre::Real)(f-n);
941  f_p_n = (Ogre::Real)(f+n);
942  px = (Ogre::Real)mcam.get_px();
943  py = (Ogre::Real)mcam.get_py();
944  u0 = (Ogre::Real)mcam.get_u0();
945  v0 = (Ogre::Real)mcam.get_v0();
946  Ogre::Matrix4 Projection
947  = Ogre::Matrix4( (Ogre::Real)(2.0*px/mBackgroundWidth), 0, (Ogre::Real)(1.0 - 2.0*(u0/mBackgroundWidth)), 0,
948  0, (Ogre::Real)(2.0*py/mBackgroundHeight), (Ogre::Real)(-1.0 + 2.0*(v0/mBackgroundHeight)),0,
949  0, 0, (Ogre::Real)(-1.0*f_p_n/f_m_n), (Ogre::Real)(-2.0*f*n/f_m_n),
950  0, 0, -1.0, 0);
951  mCamera->setCustomProjectionMatrix(true, Projection);
952  }
953 }
954 
959 {
960  // Inspired from Ogre wiki : http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
961  // Lock the pixel buffer and get a pixel box. HBL_DISCARD is to use for best
962  // performance than HBL_NORMAL
963  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
964  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
965  // Buffer data
966  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
967  // Fill in the data in the grey level texture
968  memcpy(pDest, I.bitmap, mBackgroundHeight*mBackgroundWidth);
969 
970  // Unlock the pixel buffer
971  mPixelBuffer->unlock();
972 }
973 
978 {
979  // Inspired from Ogre wiki : http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
980  // Lock the pixel buffer and get a pixel box. HBL_DISCARD is to use for best
981  // performance than HBL_NORMAL
982  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // Lock the buffer
983  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
984  // Buffer data
985  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
986  // Fill in the data in the grey level texture
987 #if 1 // if texture in BGRa format
988  for(unsigned int i=0; i<mBackgroundHeight; i++){
989  for(unsigned int j=0; j<mBackgroundWidth; j++){
990  // Color Image
991 // *pDest++=I[i][mBackgroundWidth-j].B; // Blue component
992 // *pDest++=I[i][mBackgroundWidth-j].G; // Green component
993 // *pDest++=I[i][mBackgroundWidth-j].R; // Red component
994 
995  *pDest++=I[i][j].B; // Blue component
996  *pDest++=I[i][j].G; // Green component
997  *pDest++=I[i][j].R; // Red component
998 
999  *pDest++ = 255; // Alpha component
1000  }
1001  }
1002 #else // if texture in RGBa format which is the format of the input image
1003  memcpy(pDest, I.bitmap, mBackgroundHeight*mBackgroundWidth*sizeof(vpRGBa));
1004 #endif
1005 
1006  // Unlock the pixel buffer
1007  mPixelBuffer->unlock();
1008 }
1009 
1014 {
1015  // The matrix is given to Ogre with some changes to fit with the world projection
1016  Ogre::Matrix4 ModelView
1017 // = Ogre::Matrix4( (Ogre::Real)-cMo[0][0], (Ogre::Real)-cMo[0][1], (Ogre::Real)-cMo[0][2], (Ogre::Real)-cMo[0][3],
1018  = Ogre::Matrix4( (Ogre::Real)cMw[0][0], (Ogre::Real)cMw[0][1], (Ogre::Real)cMw[0][2], (Ogre::Real)cMw[0][3],
1019  (Ogre::Real)-cMw[1][0], (Ogre::Real)-cMw[1][1], (Ogre::Real)-cMw[1][2], (Ogre::Real)-cMw[1][3],
1020  (Ogre::Real)-cMw[2][0], (Ogre::Real)-cMw[2][1], (Ogre::Real)-cMw[2][2], (Ogre::Real)-cMw[2][3],
1021  (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)0, (Ogre::Real)1);
1022  mCamera->setCustomViewMatrix(true, ModelView);
1023 }
1024 
1032 {
1034  Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("rtf");
1035 //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) )
1036 // .dynamicCast<Ogre::Texture>();
1037 //#else
1038 // ;
1039 //#endif
1040  Ogre::RenderTexture* RTarget = dynTexPtr->getBuffer()->getRenderTarget();
1041  mWindow->update();
1042  RTarget->update();
1043  if(I.getHeight() != mWindow->getHeight() || I.getWidth() != mWindow->getWidth()){
1044  I.resize(mWindow->getHeight(), mWindow->getWidth());
1045  }
1046  Ogre::HardwarePixelBufferSharedPtr mPixelBuffer = dynTexPtr->getBuffer();
1047  mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
1048  const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock();
1049  dynTexPtr->getBuffer()->blitToMemory(pixelBox);
1050  Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
1051 #if 1 // if texture in BGRa format
1052  for(unsigned int i=0; i<I.getHeight(); i++){
1053  for(unsigned int j=0; j<I.getWidth(); j++){
1054  // Color Image
1055  I[i][j].B = *pDest++; // Blue component
1056  I[i][j].G = *pDest++; // Green component
1057  I[i][j].R = *pDest++; // Red component
1058  I[i][j].A = *pDest++; // Alpha component
1059  }
1060  }
1061 #else // if texture in RGBa format which is the format of the input image
1062  memcpy(I.bitmap, pDest, I.getHeight()*I.getWidth()*sizeof(vpRGBa));
1063 #endif
1064 
1065  // Unlock the pixel buffer
1066  mPixelBuffer->unlock();
1067 
1068 }
1069 
1070 
1071 #endif
1072 
virtual void updateBackgroundTexture(const vpImage< unsigned char > &I)
Definition: vpAROgre.cpp:958
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:664
Ogre::String name
Definition: vpAROgre.h:356
void setRotation(const std::string &name, const vpRotationMatrix &wRo)
Definition: vpAROgre.cpp:675
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:529
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:756
void addRotation(const std::string &name, const vpRotationMatrix &wRo)
Definition: vpAROgre.cpp:693
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:552
bool continueRendering(void)
Definition: vpAROgre.cpp:620
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:588
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:1013
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:628
virtual ~vpAROgre(void)
Definition: vpAROgre.cpp:431
Ogre::Camera * mCamera
Definition: vpAROgre.h:360
Generic class defining intrinsic camera parameters.
virtual void closeOIS(void)
Definition: vpAROgre.cpp:916
void setVisibility(const std::string &name, bool isVisible)
Definition: vpAROgre.cpp:733
virtual bool updateScene(const Ogre::FrameEvent &)
Definition: vpAROgre.h:310
virtual void windowClosed(Ogre::RenderWindow *rw)
Definition: vpAROgre.cpp:541
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:1031
virtual bool customframeStarted(const Ogre::FrameEvent &evt)
Definition: vpAROgre.cpp:509
unsigned int mBackgroundHeight
Definition: vpAROgre.h:378
double get_px() const
virtual void updateCameraProjection(void)
Definition: vpAROgre.cpp:934
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:745
unsigned int getHeight() const
Definition: vpImage.h:152
void setPosition(const std::string &name, const vpTranslationVector &wTo)
Definition: vpAROgre.cpp:651
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:638
Class that consider the case of a translation vector.