Thursday, September 06, 2007

A Simple OpenGL Sample as Firefox plugin


Introduction

It does OpenGL rendering as Firefox plugin. Don't know whether it's useful. I did it for fun!

Background

I was trying to render x3d file with OpenGL as a Firefox plugin. I know there are many such x3d file viewers, but mine intends to handle haptic field...well, this sample is just a by-product.

Tinkering the code

You will first need to download Gecko plugin API and Firefox source code.

Download Gecko SDK extract to \yourroot\gecko-sdk\

Download Firefox source code from here, extract to \yourroot\mazilla. Then we start from a basic plugin sample, come 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, will be successed 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 successed, we continue...

Open plugin.cpp, after

#include "plugin.h"

add

#include <gl/gl.h>

then after the line

static WNDPROC lpOldProc = NULL; add two functions EnableOpenGL and DisableOpenGL

void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC);
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC);

and in

NPBool nsPluginInstance::init(NPWindow* aWindow)

{

.................

//we add EnableOpenGL and SetTimmer

 EnableOpenGL( mhWnd, &hDC, &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;hRC );
SetTimer(mhWnd, 0, 1, (TIMERPROC) NULL);
// no timer callback

............

}

then in

void nsPluginInstance::shut()

{

// subclass it back

//We add DisableOpenGL

    DisableOpenGL( mhWnd, hDC, hRC );

....

}

then in PluginWinProc we need to handle WM_TIMMER message like the following

   case WM_TIMER:
theta += 1.0f;
PostMessage( hWnd, WM_PAINT, NULL, NULL );
break;

At last we do OpenGL rendering in case WM_PAINT, remove the original code under this case, and replace them with ours as the following:

    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT );
glPushMatrix();
glRotatef( theta, 0.0f, 0.0f, 1.0f );
glBegin( GL_TRIANGLES );
glColor3f( 1.0f, 0.0f, 0.0f );
glVertex2f( 0.0f, 1.0f );
glColor3f( 0.0f, 1.0f, 0.0f );
glVertex2f( 0.87f, -0.5f );
glColor3f( 0.0f, 0.0f, 1.0f );
glVertex2f( -0.87f, -0.5f );
glEnd();
glPopMatrix();
SwapBuffers( hDC );

it's almost done, but don't forget to define EnableOpenGL and DisableOpenGL

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 );

}

Done!!!

Build the Project

Nothing to say, just build it.

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, you would see a rotating triangle, corlorful...

Another way to test the plugin. If we open a file of the type a plugin 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 changed it to hx3d. Next, create an empty file with the extension .hx3d, I created testbasic.hx3d under my folder. In firefox url box type c:\r.wang\testbasic.hx3d, you would also see the plugin triangle

Now, em....enjoy.
.
.
.
------

2 Comments:

Blogger Unknown said...

Hey, nice post, but I got a small problem compiling the plugin, I keep getting the following error:

1>c:\gecko\gecko-sdk\include\prcpucfg.h(651) : fatal error C1189: #error : "Unknown CPU architecture"

Any ideas?

5:13 PM  
Anonymous Anonymous said...

Hi i am new to plugin implementation. I saw ur post. it is good.i have to implement socket related functionalities in browser is it possible

9:19 PM  

Post a Comment

<< Home