65.9K
CodeProject is changing. Read more.
Home

An OpenGL Sample as Firefox Plugin

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (17 votes)

Sep 13, 2007

2 min read

viewsIcon

124785

downloadIcon

2245

A tutorial on how a Firefox plugin does OpenGL rendering

Sample Image - maximum width is 600 pixels

Introduction

This articles explains how OpenGL is rendered as a Firefox plugin. I don't know whether it's useful. I did it for fun!

Background

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

Tinkering with the Code

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...

Open plugin.cpp, then

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

Add EnableOpenGL and SetTimer as shown below:

NPBool nsPluginInstance::init(NPWindow* aWindow)
{
.................

    //we add EnableOpenGL and SetTimer

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

............
}

Then, add DisableOpenGL as shown below:

void nsPluginInstance::shut() 
{
    // subclass it back 


    // We add DisableOpenGL


    DisableOpenGL( mhWnd, hDC, hRC );
.... } 

After that, in PluginWinProc, we need to handle WM_TIMER message like the following:

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

At last we do OpenGL rendering in the case of WM_PAINT, remove the original code under this case, and replace it with our code as follows:

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

It's done!

Build the Project

Nothing to say, just

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

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 changed it to hx3d. Next, create an empty file with the extension .hx3d, I created testbasic.hx3d under my folder. In the Firefox URL box, type c:\r.wang\testbasic.hx3d, you would also see the plugin triangle.

Now... enjoy!