Hi all,
as posted above in the thread "reading a node file from http", I have
assembled a small firefox-plugin to display osg-files.
It is not yet "packed", I will have to carefully read the documentation
on how to do this (I would like the plugin to be downloaded
automatically when a user does not have it).
If someone would like to try it:
- it´s windows only, firefox 3.04 only (newer versions should work)
- you must have osg2.7.6 installed, bin-dir in your path. The plugin is
compiled with VC 2005, so maybe only this will work
- download the plugin here:
http://raumgeometrie.de/testplugin/npbasic.dll (it´s so small, not even
worth zipping)
- testpages here: http://www.raumgeometrie.de/testplugin/gallery.html
I attach the source to the plugin. But be aware of the fact, that the
most time-consuming step of building this plugin was to get the
basic-example I started with to compile. I will send a zip with
project-file later on.
Note that the sample-plugins shipped with the firefox-source do use
completely different function-names than those described in the
plugin-api that can be read on the firefox-dev site. I sticked to the
functions named in the sample (and had to research with google for some
things). I don´t know if their own samples are outdated, or if the
api-documentation is outdated or whatever.
The thing that does not (!) work is to put several instances of the
plugin on one page. Maybe robert can jump in and explain how the
window = viewer->setUpViewerAsEmbeddedInWindow(100,100,800,600);
viewer->setSceneData(loadedModel.get());
(which works like next to magic for me)
does find it´s OpenGL-context. Probably this is not so easy when there
is more than one context.
But even if this won´t work, it´s quite a nice plugin so far. Read the
source as an inspiration on how very easy this was - hopefully someone
can jump in and do this for linux and mac.
Regards,
Andreas
/*OpenSceneGraph Firefox-plugin
*License: GPL 2.0
*Based on Work by Mozilla.org and OpenSceneGraph osgviewerGLUT-sample by Robert Osfield
*(c) Andreas Goebel 2008
*/
#include <windows.h>
#include <windowsx.h>
#include "plugin.h"
#include <gl/gl.h>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>
//Global Variables
osg::ref_ptr<osgViewer::Viewer> viewer;
osg::observer_ptr<osgViewer::GraphicsWindow> window;
char* filename;
//Functions that translate the Windows Mouse-Events to osg-events
void mousebutton( int button, int state, int x, int y )
{
if (window.valid())
{
if (state==0) window->getEventQueue()->mouseButtonPress( x, y, button+1 );
else window->getEventQueue()->mouseButtonRelease( x, y, button+1 );
}
}
void mousemove( int x, int y )
{
if (window.valid())
{
window->getEventQueue()->mouseMotion( x, y );
}
}
//////////////////////////////////////
//
// general initialization and shutdown
//
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);
filename = aCreateDataStruct->argv[0]; //This structs holds tha value passed to the plugin with embed
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()
{
}
static LRESULT CALLBACK PluginWinProc(HWND, UINT, WPARAM, LPARAM);
static WNDPROC lpOldProc = NULL;
void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC);
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC);
HDC hDC;
HGLRC hRC;
NPBool nsPluginInstance::init(NPWindow* aWindow)
{
if(aWindow == NULL)
return FALSE;
mhWnd = (HWND)aWindow->window;
if(mhWnd == NULL)
return FALSE;
// 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);
//we add EnableOpenGL and SetTimer
EnableOpenGL( mhWnd, &hDC, &hRC );
SetTimer(mhWnd, 0, 1, (TIMERPROC) NULL); // no timer callback
//osg-related code:
//Node-file is read via http by libcurl:
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(filename);
viewer = new osgViewer::Viewer;
window = viewer->setUpViewerAsEmbeddedInWindow(100,100,800,600);
viewer->setSceneData(loadedModel.get());
viewer->setCameraManipulator(new osgGA::TrackballManipulator);
viewer->addEventHandler(new osgViewer::StatsHandler);
viewer->realize();
mInitialized = TRUE;
return TRUE;
}
void nsPluginInstance::shut()
{
// We add DisableOpenGL
DisableOpenGL( mhWnd, hDC, hRC );
// subclass it back
SubclassWindow(mhWnd, lpOldProc);
mhWnd = NULL;
mInitialized = FALSE;
}
NPBool nsPluginInstance::isInitialized()
{
return mInitialized;
}
const char * nsPluginInstance::getVersion()
{
return NPN_UserAgent(mInstance);
}
static LRESULT CALLBACK PluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_PAINT:
{
if (viewer.valid()) viewer->frame();
SwapBuffers( hDC );
}
break;
case WM_TIMER:
PostMessage( hWnd, WM_PAINT, NULL, NULL );
break;
case WM_LBUTTONDOWN:
{
short xp = LOWORD(lParam);
short yp = HIWORD(lParam);
mousebutton(0,0,xp,yp);
break;
}
case WM_LBUTTONUP:
{
short xp = LOWORD(lParam);
short yp = HIWORD(lParam);
mousebutton(0,1,xp,yp);
break;
}
case WM_RBUTTONDOWN:
{
short xp = LOWORD(lParam);
short yp = HIWORD(lParam);
mousebutton(2,0,xp,yp);
}
break;
case WM_RBUTTONUP:
{
short xp = LOWORD(lParam);
short yp = HIWORD(lParam);
mousebutton(2,1,xp,yp);
break;
}
case WM_MOUSEMOVE:
{
short xp = LOWORD(lParam);
short yp = HIWORD(lParam);
mousemove(xp,yp);
break;
}
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int format;
// get the device context (DC)
*hDC = GetDC( hWnd ); // set the pixel format for the DC
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat( *hDC, &pfd );
SetPixelFormat( *hDC, format, &pfd );
// create and enable the render context (RC)
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );
}
// Disable OpenGL
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hRC );
ReleaseDC( hWnd, hDC );
} _______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org