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

Reply via email to