Embedding ogre in firefox

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!

Embedding ogre in firefox

Postby dudeabot » Sun Mar 15, 2009 2:04 pm

hello, last day i did some testings trying to embed ogre3d on firefox, most of the step by step i got from

http://www.codeproject.com/KB/openGL/FirefoxOpenGL

so lets quote it a bit:

You will first need to download Gecko plugin API and Firefox source code. Download Gecko SDK and extract to \yourroot\gecko-sdk\.

Download Firefox source code from here, extract to \yourroot\mozilla.
Then we start from a basic plugin sample. Go to the folder: yourroot\mozilla\modules\plugin\tools\sdk\samples\basic\windows.



Here's a little trick, we need to run unix2dos on npbasic.dsp and npbasic.dsw under this folder. Then we open and cover the project by Visual C++ Express, we will be successful now. From project properties, change the Additional include directories to yourroot\gecko-sdk\include; yourroot\mozilla\modules\plugin\tools\sdk\samples\include. Try to build now, if successful, we continue...
NOTE: well i prefer just open on wordpad, press enter and save it :P


updated download links:
http://developer.mozilla.org/en/docs/Gecko_SDK
ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/source/firefox-3.0.7-source.tar.bz2 (this is for 3.0, doh =P)

ok so lets make some changes to the plugin.cpp file (this is heavily based on embbeded aplication on playpen)

you can download the code http://gp.leveldesign.com.br/plugin.rar (i havent put basic.rc because mine is slightly modified - use the one that comes with the example. Also make sure you correct the library and include paths on project seetings to your ogre folder)

Code: Select all
#include <windows.h>
#include <windowsx.h>
#include "plugin.h"

#include "Ogre.h"
#include "OgreCgPlugin.h"
#include "OgreD3D9Plugin.h"

static LRESULT CALLBACK PluginWinProc(HWND, UINT, WPARAM, LPARAM);
static WNDPROC lpOldProc = NULL;

using namespace Ogre;
//using namespace OIS;

HWND mhWnd=0;
RenderWindow* renderWindow=0;
bool winActive = false;
bool winSizing = false;

static LRESULT CALLBACK PluginWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   if (message == WM_CREATE)
   {
      return 0;
   }

   if (!renderWindow)
      return DefWindowProc(hWnd, message, wParam, lParam);
   switch( message )
   {
   case WM_ACTIVATE:
      winActive = (LOWORD(wParam) != WA_INACTIVE);
      break;

   case WM_ENTERSIZEMOVE:
      winSizing = true;
      break;

   case WM_EXITSIZEMOVE:
      renderWindow->windowMovedOrResized();
      renderWindow->update();
      winSizing = false;
      break;

   case WM_MOVE:
   case WM_SIZE:
      if (!winSizing)
         renderWindow->windowMovedOrResized();
      break;

   case WM_GETMINMAXINFO:
      // Prevent the window from going smaller than some min size
      ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
      ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
      break;

   case WM_CLOSE:
      renderWindow->destroy(); // cleanup and call DestroyWindow
      PostQuitMessage(0);
      return 0;
   case WM_PAINT:
      if (!winSizing)
      {
         renderWindow->update();
         return 0;
      }
      break;
   }
   return DefWindowProc( hWnd, message, wParam, lParam );
}


NPError NS_PluginInitialize()
{
   return NPERR_NO_ERROR;
}

void NS_PluginShutdown()
{
}

/////////////////////////////////////////////////////////////
//
// construction and destruction of our plugin instance object
//
nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)
{
   if(!aCreateDataStruct)
      return NULL;

   nsPluginInstance * plugin = new nsPluginInstance(aCreateDataStruct->instance);
   return plugin;
}

void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin)
{
   if(aPlugin)
      delete (nsPluginInstance *)aPlugin;
}

////////////////////////////////////////
//
// nsPluginInstance class implementation
//
nsPluginInstance::nsPluginInstance(NPP aInstance) : nsPluginInstanceBase(),
mInstance(aInstance),
mInitialized(FALSE)
{
   mhWnd = NULL;
}

nsPluginInstance::~nsPluginInstance()
{
}

void setupResources(void)
{
   // Load resource paths from config file
   ConfigFile cf;
   cf.load("resources.cfg");

   // Go through all sections & settings in the file
   ConfigFile::SectionIterator seci = cf.getSectionIterator();

   String secName, typeName, archName;
   while (seci.hasMoreElements())
   {
      secName = seci.peekNextKey();
      ConfigFile::SettingsMultiMap *settings = seci.getNext();
      ConfigFile::SettingsMultiMap::iterator i;
      for (i = settings->begin(); i != settings->end(); ++i)
      {
         typeName = i->first;
         archName = i->second;
         ResourceGroupManager::getSingleton().addResourceLocation(
            archName, typeName, secName);
      }
   }
}


NPBool nsPluginInstance::init(NPWindow* aWindow)
{
   if(aWindow == NULL)
      return FALSE;

   mhWnd = (HWND)aWindow->window;
   if(mhWnd == NULL)
      return FALSE;

   D3D9Plugin* mD3D9Plugin = new D3D9Plugin();
   CgPlugin* mCgPlugin = new CgPlugin();
   try{
      //we add EnableOpenGL and SetTimer
      Root root("", "");
         root.installPlugin(mD3D9Plugin);
         root.installPlugin(mCgPlugin);

      // select first renderer & init with no window
      root.setRenderSystem(*(root.getAvailableRenderers()->begin()));
      root.initialise(false);

      // create first window manually
      NameValuePairList options;
      options["parentWindowHandle"] =
         StringConverter::toString((size_t)mhWnd);

      renderWindow = root.createRenderWindow("embedded", 800, 600, false, &options);

      setupResources();
      ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

      SceneManager *scene = root.createSceneManager(Ogre::ST_GENERIC, "default");


      Camera *cam = scene->createCamera("cam");

      Viewport* vp = renderWindow->addViewport(cam);
      vp->setBackgroundColour(Ogre::ColourValue(0.5, 0.5, 0.7));
      cam->setAutoAspectRatio(true);
      cam->setPosition(0,0,300);
      cam->setDirection(0,0,-1);

      Entity* e = scene->createEntity("1", "ogrehead.mesh");
      scene->getRootSceneNode()->createChildSceneNode()->attachObject(e);
      Light* l = scene->createLight("l");
      l->setPosition(300, 100, -100);

      /*LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");*/

      

      // subclass window so we can intercept window messages and
      // do our drawing to it
      lpOldProc = SubclassWindow(mhWnd, (WNDPROC)PluginWinProc);

      // associate window with our nsPluginInstance object so we can access
      // it in the window procedure
      SetWindowLong(mhWnd, GWL_USERDATA, (LONG)this);

      //OIS::InputManager* mInputManager;
      //OIS::ParamList pl;
      //size_t windowHnd = 0;
      //std::ostringstream windowHndStr;

      //renderWindow->getCustomAttribute("WINDOW", &windowHnd);
      //windowHndStr << (size_t)windowHnd;
      //pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

      //LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");

      ////OIS Input devices
      //OIS::Keyboard* mKeyboard;

      //mInputManager = OIS::InputManager::createInputSystem( pl );
      ////OIS::Mouse*    mMouse;

      //LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");

      ////Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
      ////mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, false ));
      //mKeyboard = (OIS::Keyboard*)mInputManager->createInputObject( OIS::OISKeyboard, false );
      ////mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
      
      // subclass window so we can intercept window messages and
      // do our drawing to it
      lpOldProc = SubclassWindow(mhWnd, (WNDPROC)PluginWinProc);

      // associate window with our nsPluginInstance object so we can access
      // it in the window procedure
      SetWindowLong(mhWnd, GWL_USERDATA, (LONG)this);
      SetTimer(mhWnd,             // handle to main window
         0,                   // timer identifier
         1,                   // 10-second interval
         (TIMERPROC) NULL);       // no timer callback       
      mInitialized = TRUE;

      // message loop
      MSG msg;
      while(GetMessage(&msg, NULL, 0, 0 ) != 0)
      {
         //mKeyboard->capture();
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
   }
   catch( Ogre::Exception& e )
   {
      MessageBox( NULL, e.getFullDescription().c_str(),
         "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);

   }
   delete mCgPlugin;
   delete mD3D9Plugin;

   return TRUE;
}

void nsPluginInstance::shut()
{
   // subclass it back
   SubclassWindow(mhWnd, lpOldProc);
   mhWnd = NULL;
   mInitialized = FALSE;
   
}

NPBool nsPluginInstance::isInitialized()
{
   return mInitialized;
}

const char * nsPluginInstance::getVersion()
{
   return NPN_UserAgent(mInstance);
}


now compile it (you should link statically against ogre, renders, etc)

Test the plugin

Copy npbasic.dll to C:\Program Files\Mozilla Firefox\plugins\ or yourfolder\Mozilla Firefox\plugins\.
From the folder yourroot\mozilla\modules\plugin\tools\sdk\samples\basic\, you will find test.html, double click

Another way to test the plugin

If we open a file of the type that a plugin is registered, then the plugin will be triggered. Open basic.rc with a text editor, find the string "FileExtents" and change the value to whatever you want. I left it as .bic, the default value.

Image
beatiful :D



PROBLEMS:
1)when i close the firefox tab or window, that .dll isnt unloaded, i still dunno why, you will have to close it from task bar probably
2)Having problems to link with OIS.
3) if you have problem compiling:

in the header file npplat.h

move the block:

#ifdef XP_WIN
#include "windows.h"
#endif //XP_WIN

to the top, not the exact top, but comes before all the other includes.





maybe some one with more knowledge on npapi can help solve these problems :)
dudeabot
Gnome
 
Posts: 334
Kudos: 6
Joined: 28 Jun 2007
Location: Brazil

Re: Embedding ogre in firefox

Postby Azgur » Sun Mar 15, 2009 6:21 pm

All you need now is to add the old Navi that still uses Gecko to that Ogre scene :)
User avatar
Azgur
Goblin
 
Posts: 264
Kudos: 0
Joined: 21 Aug 2008


Return to Showcase

Who is online

Users browsing this forum: No registered users and 7 guests