Ported example to using OSG objects for rendering rather than GLUT
This commit is contained in:
@@ -5,588 +5,480 @@
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Linden Lab Inc. (http://lindenlab.com) code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is:
|
||||
* Callum Prentice (callum@ubrowser.com)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Callum Prentice (callum@ubrowser.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <nsGUIEvent.h>
|
||||
|
||||
#include "llmozlib2.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of the test app - implemented as a class and derrives from
|
||||
// the observer so we can catch events emitted by LLMozLib
|
||||
//
|
||||
class testGL :
|
||||
public LLEmbeddedBrowserWindowObserver
|
||||
class UBrowserImage;
|
||||
|
||||
class UBrowserImage : public osg::Image, public LLEmbeddedBrowserWindowObserver
|
||||
{
|
||||
public:
|
||||
testGL() :
|
||||
mAppWindowWidth( 800 ), // dimensions of the app window - can be anything
|
||||
mAppWindowHeight( 600 ),
|
||||
mBrowserWindowWidth( mAppWindowWidth ), // dimensions of the embedded browser - can be anything
|
||||
mBrowserWindowHeight( mAppWindowHeight ), // but looks best when it's the same as the app window
|
||||
mAppTextureWidth( -1 ), // dimensions of the texture that the browser is rendered into
|
||||
mAppTextureHeight( -1 ), // calculated at initialization
|
||||
mAppTexture( 0 ),
|
||||
mNeedsUpdate( true ), // flag to indicate if browser texture needs an update
|
||||
mBrowserWindowId( 0 ),
|
||||
mAppWindowName( "testGL" ),
|
||||
//mHomeUrl( "http://www.google.com" )
|
||||
mHomeUrl( "http://www.google.com" )
|
||||
{
|
||||
std::cout << "LLMozLib version: " << LLMozLib::getInstance()->getVersion() << std::endl;
|
||||
};
|
||||
public:
|
||||
|
||||
UBrowserImage(const std::string& appWindowName,int width, int height);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void init( char* arg0 )
|
||||
{
|
||||
// OpenGL initialization
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.5f);
|
||||
glEnable( GL_COLOR_MATERIAL );
|
||||
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
||||
glEnable( GL_CULL_FACE );
|
||||
|
||||
// calculate texture size required (next power of two above browser window size
|
||||
for ( mAppTextureWidth = 1; mAppTextureWidth < mBrowserWindowWidth; mAppTextureWidth <<= 1 )
|
||||
{
|
||||
};
|
||||
virtual void sendPointerEvent(int x, int y, int buttonMask);
|
||||
|
||||
for ( mAppTextureHeight = 1; mAppTextureHeight < mBrowserWindowHeight; mAppTextureHeight <<= 1 )
|
||||
{
|
||||
};
|
||||
virtual void sendKeyEvent(int key, bool keyDown);
|
||||
|
||||
// create the texture used to display the browser data
|
||||
glGenTextures( 1, &mAppTexture );
|
||||
glBindTexture( GL_TEXTURE_2D, mAppTexture );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexImage2D( GL_TEXTURE_2D, 0,
|
||||
GL_RGB,
|
||||
mAppTextureWidth, mAppTextureHeight,
|
||||
0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
|
||||
void navigateTo(const std::string& page);
|
||||
|
||||
|
||||
// create a single browser window and set things up.
|
||||
std::string applicationDir = osgDB::getFilePath(arg0);
|
||||
if (applicationDir.empty()) applicationDir = osgDB::getRealPath(".");
|
||||
else applicationDir = osgDB::getRealPath(applicationDir);
|
||||
|
||||
std::string componentDir = "/usr/lib/xulrunner";
|
||||
std::string profileDir = applicationDir + "/" + "testGL_profile";
|
||||
LLMozLib::getInstance()->init( applicationDir, componentDir, profileDir, getNativeWindowHandle() );
|
||||
|
||||
|
||||
mBrowserWindowId = LLMozLib::getInstance()->createBrowserWindow( mBrowserWindowWidth, mBrowserWindowHeight );
|
||||
|
||||
std::cout<<"after createBrowserWindow("<<mBrowserWindowWidth<<", "<<mBrowserWindowHeight<<") mBrowserWindowId = "<<mBrowserWindowId<<std::endl;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onPageChanged( const EventType& eventIn )
|
||||
{
|
||||
// flag that an update is required - page grab happens in idle() so we don't stall
|
||||
_needsUpdate = true;
|
||||
};
|
||||
|
||||
// tell LLMozLib about the size of the browser window
|
||||
LLMozLib::getInstance()->setSize( mBrowserWindowId, mBrowserWindowWidth, mBrowserWindowHeight );
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onNavigateBegin( const EventType& eventIn )
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Event: begin navigation to " << eventIn.getEventUri() << std::endl;
|
||||
};
|
||||
|
||||
// observer events that LLMozLib emits
|
||||
LLMozLib::getInstance()->addObserver( mBrowserWindowId, this );
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onNavigateComplete( const EventType& eventIn )
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Event: end navigation to " << eventIn.getEventUri() << " with response status of " << eventIn.getIntValue() << std::endl;
|
||||
};
|
||||
|
||||
// append details to agent string
|
||||
LLMozLib::getInstance()->setBrowserAgentId( mAppWindowName );
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onUpdateProgress( const EventType& eventIn )
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Event: progress value updated to " << eventIn.getIntValue() << std::endl;
|
||||
};
|
||||
|
||||
// don't flip bitmap
|
||||
LLMozLib::getInstance()->flipWindow( mBrowserWindowId, false );
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onStatusTextChange( const EventType& eventIn )
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Event: status updated to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
// go to the "home page"
|
||||
LLMozLib::getInstance()->navigateTo( mBrowserWindowId, mHomeUrl );
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onLocationChange( const EventType& eventIn )
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Event: location changed to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void reset( void )
|
||||
{
|
||||
// unhook observer
|
||||
LLMozLib::getInstance()->remObserver( mBrowserWindowId, this );
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onClickLinkHref( const EventType& eventIn )
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Event: clicked on link to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
// clean up
|
||||
LLMozLib::getInstance()->reset();
|
||||
};
|
||||
void update();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void reshape( int widthIn, int heightIn )
|
||||
{
|
||||
if ( heightIn == 0 )
|
||||
heightIn = 1;
|
||||
void* getNativeWindowHandle();
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
protected:
|
||||
|
||||
glViewport( 0, 0, widthIn, heightIn );
|
||||
glOrtho( 0.0f, widthIn, heightIn, 0.0f, -1.0f, 1.0f );
|
||||
virtual ~UBrowserImage();
|
||||
|
||||
void setUpKeyMap();
|
||||
|
||||
int convertToXULKey(int key) const;
|
||||
|
||||
// we use these elsewhere so save
|
||||
mAppWindowWidth = widthIn;
|
||||
mAppWindowHeight = heightIn;
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
glutPostRedisplay();
|
||||
};
|
||||
|
||||
void idle();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void display()
|
||||
{
|
||||
//std::cout<<"display() mBrowserWindowId = "<<mBrowserWindowId<<std::endl;
|
||||
|
||||
// clear screen
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
glLoadIdentity();
|
||||
|
||||
// use the browser texture
|
||||
glBindTexture( GL_TEXTURE_2D, mAppTexture );
|
||||
|
||||
// valid window ?
|
||||
if ( mBrowserWindowId )
|
||||
{
|
||||
static int count = 0;
|
||||
count++;
|
||||
|
||||
// needs to be updated?
|
||||
if ( mNeedsUpdate && (count%1)==0)
|
||||
{
|
||||
// grab the page
|
||||
// std::cout<<"mNeedsUpdate = true"<<std::endl;
|
||||
|
||||
const unsigned char* pixels = LLMozLib::getInstance()->getBrowserWindowPixels( mBrowserWindowId );
|
||||
if ( pixels )
|
||||
{
|
||||
|
||||
//std::cout<<"Texture subload "<<LLMozLib::getInstance()->getBrowserRowSpan( mBrowserWindowId ) / LLMozLib::getInstance()->getBrowserDepth( mBrowserWindowId )<<", "<<mBrowserWindowHeight<<std::endl;
|
||||
|
||||
// write them into the texture
|
||||
glTexSubImage2D( GL_TEXTURE_2D, 0,
|
||||
0, 0,
|
||||
// because sometimes the rowspan != width * bytes per pixel (mBrowserWindowWidth)
|
||||
LLMozLib::getInstance()->getBrowserRowSpan( mBrowserWindowId ) / LLMozLib::getInstance()->getBrowserDepth( mBrowserWindowId ),
|
||||
mBrowserWindowHeight,
|
||||
LLMozLib::getInstance()->getBrowserDepth( mBrowserWindowId ) == 3 ? GL_BGR_EXT : GL_BGRA_EXT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
pixels );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"No data to subload"<<std::endl;
|
||||
}
|
||||
|
||||
// flag as already updated
|
||||
//mNeedsUpdate = false;
|
||||
};
|
||||
};
|
||||
|
||||
// scale the texture so that it fits the screen
|
||||
GLfloat textureScaleX = ( GLfloat )mBrowserWindowWidth / ( GLfloat )mAppTextureWidth;
|
||||
GLfloat textureScaleY = ( GLfloat )mBrowserWindowHeight / ( GLfloat )mAppTextureHeight;
|
||||
|
||||
// draw the single quad full screen (orthographic)
|
||||
glMatrixMode( GL_TEXTURE );
|
||||
glPushMatrix();
|
||||
glScalef( textureScaleX, textureScaleY, 1.0f );
|
||||
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
glBegin( GL_QUADS );
|
||||
glTexCoord2f( 1.0f, 0.0f );
|
||||
glVertex2d( mAppWindowWidth, 0 );
|
||||
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex2d( 0, 0 );
|
||||
|
||||
glTexCoord2f( 0.0f, 1.0f );
|
||||
glVertex2d( 0, mAppWindowHeight );
|
||||
|
||||
glTexCoord2f( 1.0f, 1.0f );
|
||||
glVertex2d( mAppWindowWidth, mAppWindowHeight );
|
||||
glEnd();
|
||||
|
||||
glMatrixMode( GL_TEXTURE );
|
||||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void mouseButton( int button, int state, int xIn, int yIn )
|
||||
{
|
||||
// texture is scaled to fit the screen so we scale mouse coords in the same way
|
||||
xIn = ( xIn * mBrowserWindowWidth ) / mAppWindowWidth;
|
||||
yIn = ( yIn * mBrowserWindowHeight ) / mAppWindowHeight;
|
||||
|
||||
if ( button == GLUT_LEFT_BUTTON )
|
||||
{
|
||||
if ( state == GLUT_DOWN )
|
||||
{
|
||||
// send event to LLMozLib
|
||||
LLMozLib::getInstance()->mouseDown( mBrowserWindowId, xIn, yIn );
|
||||
}
|
||||
else
|
||||
if ( state == GLUT_UP )
|
||||
{
|
||||
// send event to LLMozLib
|
||||
LLMozLib::getInstance()->mouseUp( mBrowserWindowId, xIn, yIn );
|
||||
|
||||
// this seems better than sending focus on mouse down (still need to improve this)
|
||||
LLMozLib::getInstance()->focusBrowser( mBrowserWindowId, true );
|
||||
};
|
||||
};
|
||||
|
||||
// force a GLUT update
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void mouseMove( int xIn , int yIn )
|
||||
{
|
||||
// texture is scaled to fit the screen so we scale mouse coords in the same way
|
||||
xIn = ( xIn * mBrowserWindowWidth ) / mAppWindowWidth;
|
||||
yIn = ( yIn * mBrowserWindowHeight ) / mAppWindowHeight;
|
||||
|
||||
// send event to LLMozLib
|
||||
LLMozLib::getInstance()->mouseMove( mBrowserWindowId, xIn, yIn );
|
||||
|
||||
// force a GLUT update
|
||||
glutPostRedisplay();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void keyboard( unsigned char keyIn, int xIn, int yIn )
|
||||
{
|
||||
// ESC key exits
|
||||
if ( keyIn == 27 )
|
||||
{
|
||||
reset();
|
||||
|
||||
exit( 0 );
|
||||
};
|
||||
|
||||
// send event to LLMozLib
|
||||
if (keyIn<32) LLMozLib::getInstance()->keyPress( mBrowserWindowId, keyIn );
|
||||
else LLMozLib::getInstance()->unicodeInput( mBrowserWindowId, keyIn );
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onPageChanged( const EventType& eventIn )
|
||||
{
|
||||
// flag that an update is required - page grab happens in idle() so we don't stall
|
||||
mNeedsUpdate = true;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onNavigateBegin( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "Event: begin navigation to " << eventIn.getEventUri() << std::endl;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onNavigateComplete( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "Event: end navigation to " << eventIn.getEventUri() << " with response status of " << eventIn.getIntValue() << std::endl;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onUpdateProgress( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "Event: progress value updated to " << eventIn.getIntValue() << std::endl;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onStatusTextChange( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "Event: status updated to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onLocationChange( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "Event: location changed to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual
|
||||
void onClickLinkHref( const EventType& eventIn )
|
||||
{
|
||||
std::cout << "Event: clicked on link to " << eventIn.getStringValue() << std::endl;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int getAppWindowWidth()
|
||||
{
|
||||
return mAppWindowWidth;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int getAppWindowHeight()
|
||||
{
|
||||
return mAppWindowHeight;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
std::string getAppWindowName()
|
||||
{
|
||||
return mAppWindowName;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void* getNativeWindowHandle();
|
||||
|
||||
private:
|
||||
int mAppWindowWidth;
|
||||
int mAppWindowHeight;
|
||||
int mBrowserWindowWidth;
|
||||
int mBrowserWindowHeight;
|
||||
int mAppTextureWidth;
|
||||
int mAppTextureHeight;
|
||||
GLuint mAppTexture;
|
||||
int mBrowserWindowId;
|
||||
std::string mAppWindowName;
|
||||
std::string mHomeUrl;
|
||||
bool mNeedsUpdate;
|
||||
int _browserWindowId;
|
||||
void* _nativeWindowHandle;
|
||||
|
||||
int _previousButtonMask;
|
||||
bool _needsUpdate;
|
||||
|
||||
typedef std::map<int, int> KeyMap;
|
||||
KeyMap _keyMap;
|
||||
};
|
||||
|
||||
testGL* theApp;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
UBrowserImage::UBrowserImage(const std::string& appWindowName,int width, int height):
|
||||
_nativeWindowHandle(0),
|
||||
_browserWindowId(0),
|
||||
_previousButtonMask(0),
|
||||
_needsUpdate(true)
|
||||
{
|
||||
setUpKeyMap();
|
||||
|
||||
// create a single browser window and set things up.
|
||||
std::string applicationDir = osgDB::getFilePath(appWindowName);
|
||||
if (applicationDir.empty()) applicationDir = osgDB::getRealPath(".");
|
||||
else applicationDir = osgDB::getRealPath(applicationDir);
|
||||
|
||||
std::string componentDir = "/usr/lib/xulrunner";
|
||||
std::string profileDir = applicationDir + "/" + "testGL_profile";
|
||||
LLMozLib::getInstance()->init( applicationDir, componentDir, profileDir, getNativeWindowHandle() );
|
||||
|
||||
_browserWindowId = LLMozLib::getInstance()->createBrowserWindow( width, height );
|
||||
|
||||
// tell LLMozLib about the size of the browser window
|
||||
LLMozLib::getInstance()->setSize( _browserWindowId, width, height );
|
||||
|
||||
// observer events that LLMozLib emits
|
||||
LLMozLib::getInstance()->addObserver( _browserWindowId, this );
|
||||
|
||||
// append details to agent string
|
||||
LLMozLib::getInstance()->setBrowserAgentId( appWindowName );
|
||||
|
||||
// don't flip bitmap
|
||||
LLMozLib::getInstance()->flipWindow( _browserWindowId, false );
|
||||
|
||||
LLMozLib::getInstance()->setBackgroundColor( _browserWindowId, 0, 255, 0);
|
||||
|
||||
navigateTo("http://www.google.com");
|
||||
|
||||
GLint internalFormat = LLMozLib::getInstance()->getBrowserDepth( _browserWindowId ) == 3 ? GL_RGB : GL_RGBA;
|
||||
GLenum pixelFormat = LLMozLib::getInstance()->getBrowserDepth( _browserWindowId ) == 3 ? GL_BGR_EXT : GL_BGRA_EXT;
|
||||
|
||||
setImage(width,height,1, internalFormat, pixelFormat, GL_UNSIGNED_BYTE,
|
||||
(unsigned char*)LLMozLib::getInstance()->getBrowserWindowPixels( _browserWindowId ),
|
||||
osg::Image::NO_DELETE);
|
||||
|
||||
setDataVariance(osg::Object::DYNAMIC);
|
||||
setOrigin(osg::Image::TOP_LEFT);
|
||||
}
|
||||
|
||||
UBrowserImage::~UBrowserImage()
|
||||
{
|
||||
}
|
||||
|
||||
void UBrowserImage::sendPointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
int deltaButton = (buttonMask&1) - (_previousButtonMask&1);
|
||||
_previousButtonMask = buttonMask;
|
||||
|
||||
if (deltaButton>0)
|
||||
{
|
||||
// send event to LLMozLib
|
||||
LLMozLib::getInstance()->mouseDown( _browserWindowId, x, y );
|
||||
}
|
||||
else if (deltaButton<0)
|
||||
{
|
||||
// send event to LLMozLib
|
||||
LLMozLib::getInstance()->mouseUp( _browserWindowId, x, y );
|
||||
|
||||
// this seems better than sending focus on mouse down (still need to improve this)
|
||||
LLMozLib::getInstance()->focusBrowser( _browserWindowId, true );
|
||||
} else
|
||||
{
|
||||
// send event to LLMozLib
|
||||
LLMozLib::getInstance()->mouseMove( _browserWindowId, x, y );
|
||||
}
|
||||
}
|
||||
|
||||
void UBrowserImage::sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
if (!keyDown) return;
|
||||
|
||||
KeyMap::const_iterator itr = _keyMap.find(key);
|
||||
if (_keyMap.find(key)==_keyMap.end()) LLMozLib::getInstance()->unicodeInput( _browserWindowId, key );
|
||||
else LLMozLib::getInstance()->keyPress( _browserWindowId, itr->second );
|
||||
}
|
||||
|
||||
void UBrowserImage::navigateTo(const std::string& url)
|
||||
{
|
||||
// go to the "home page"
|
||||
LLMozLib::getInstance()->navigateTo( _browserWindowId, url );
|
||||
}
|
||||
|
||||
|
||||
void UBrowserImage::update()
|
||||
{
|
||||
//if ( _needsUpdate )
|
||||
{
|
||||
// grab a page but don't reset 'needs update' flag until we've written it to the texture in display()
|
||||
LLMozLib::getInstance()->grabBrowserWindow( _browserWindowId );
|
||||
|
||||
int width = LLMozLib::getInstance()->getBrowserRowSpan( _browserWindowId ) / LLMozLib::getInstance()->getBrowserDepth( _browserWindowId );
|
||||
int height = LLMozLib::getInstance()->getBrowserHeight( _browserWindowId );
|
||||
|
||||
GLint internalFormat = LLMozLib::getInstance()->getBrowserDepth( _browserWindowId ) == 3 ? GL_RGB : GL_RGBA;
|
||||
GLenum pixelFormat = LLMozLib::getInstance()->getBrowserDepth( _browserWindowId ) == 3 ? GL_BGR_EXT : GL_BGRA_EXT;
|
||||
|
||||
setImage(width,height,1, internalFormat, pixelFormat, GL_UNSIGNED_BYTE,
|
||||
(unsigned char*)LLMozLib::getInstance()->getBrowserWindowPixels( _browserWindowId ),
|
||||
osg::Image::NO_DELETE);
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Image updated "<<(void*)data()<<", "<<s()<<","<<t()<<std::endl;
|
||||
|
||||
// _needsUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void idle()
|
||||
{
|
||||
//std::cout<<"idle()"<<std::endl;
|
||||
|
||||
// onPageChanged event sets this
|
||||
// if ( mNeedsUpdate )
|
||||
// grab a page but don't reset 'needs update' flag until we've written it to the texture in display()
|
||||
LLMozLib::getInstance()->grabBrowserWindow( mBrowserWindowId );
|
||||
|
||||
// lots of updates for smooth motion
|
||||
glutPostRedisplay();
|
||||
};
|
||||
|
||||
|
||||
void* testGL::getNativeWindowHandle()
|
||||
void* UBrowserImage::getNativeWindowHandle()
|
||||
{
|
||||
if (_nativeWindowHandle) return _nativeWindowHandle;
|
||||
|
||||
// My implementation of the embedded browser needs a native window handle
|
||||
// Can't get this via GLUT so had to use this hack
|
||||
return FindWindow( NULL, mAppWindowName.c_str() );
|
||||
_nativeWindowHandle = FindWindow( NULL, _appWindowName.c_str() );
|
||||
|
||||
return _nativeWindowHandle;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void testGL::idle()
|
||||
void* UBrowserImage::getNativeWindowHandle()
|
||||
{
|
||||
// pump the GTK+Gecko event queue for a (limited) while. this should
|
||||
// be done so that the Gecko event queue doesn't starve, and done
|
||||
// *here* so that mNeedsUpdate[] can be populated by callbacks
|
||||
// from Gecko.
|
||||
gtk_main_iteration_do(0);
|
||||
for (int iter=0; iter<10; ++iter)
|
||||
if (gtk_events_pending())
|
||||
gtk_main_iteration();
|
||||
if (_nativeWindowHandle) return _nativeWindowHandle;
|
||||
|
||||
gtk_disable_setlocale();
|
||||
gtk_init(NULL, NULL);
|
||||
|
||||
//std::cout<<"idle()"<<std::endl;
|
||||
GtkWidget *win = gtk_window_new(GTK_WINDOW_POPUP);
|
||||
// Why a layout widget? A MozContainer would be ideal, but
|
||||
// it involves exposing Mozilla headers to mozlib-using apps.
|
||||
// A layout widget with a GtkWindow parent has the desired
|
||||
// properties of being plain GTK, having a window, and being
|
||||
// derived from a GtkContainer.
|
||||
GtkWidget *rtnw = gtk_layout_new(NULL, NULL);
|
||||
gtk_container_add(GTK_CONTAINER(win), rtnw);
|
||||
gtk_widget_realize(rtnw);
|
||||
GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW);
|
||||
|
||||
// onPageChanged event sets this
|
||||
// if ( mNeedsUpdate )
|
||||
// grab a page but don't reset 'needs update' flag until we've written it to the texture in display()
|
||||
LLMozLib::getInstance()->grabBrowserWindow( mBrowserWindowId );
|
||||
|
||||
// lots of updates for smooth motion
|
||||
glutPostRedisplay();
|
||||
};
|
||||
|
||||
|
||||
void* testGL::getNativeWindowHandle()
|
||||
{
|
||||
gtk_disable_setlocale();
|
||||
gtk_init(NULL, NULL);
|
||||
|
||||
GtkWidget *win = gtk_window_new(GTK_WINDOW_POPUP);
|
||||
// Why a layout widget? A MozContainer would be ideal, but
|
||||
// it involves exposing Mozilla headers to mozlib-using apps.
|
||||
// A layout widget with a GtkWindow parent has the desired
|
||||
// properties of being plain GTK, having a window, and being
|
||||
// derived from a GtkContainer.
|
||||
GtkWidget *rtnw = gtk_layout_new(NULL, NULL);
|
||||
gtk_container_add(GTK_CONTAINER(win), rtnw);
|
||||
gtk_widget_realize(rtnw);
|
||||
GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW);
|
||||
|
||||
return rtnw;
|
||||
};
|
||||
_nativeWindowHandle = rtnw;
|
||||
|
||||
return _nativeWindowHandle;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void glutReshape( int widthIn, int heightIn )
|
||||
void UBrowserImage::setUpKeyMap()
|
||||
{
|
||||
if ( theApp )
|
||||
theApp->reshape( widthIn, heightIn );
|
||||
};
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_BackSpace] = nsIDOMKeyEvent::DOM_VK_BACK_SPACE;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Tab] = nsIDOMKeyEvent::DOM_VK_TAB;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Linefeed] = nsIDOMKeyEvent::DOM_VK_ENTER;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Clear] = nsIDOMKeyEvent::DOM_VK_CLEAR;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Return] = nsIDOMKeyEvent::DOM_VK_RETURN;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Pause] = nsIDOMKeyEvent::DOM_VK_PAUSE;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Scroll_Lock] = nsIDOMKeyEvent::DOM_VK_SCROLL_LOCK;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Escape] = nsIDOMKeyEvent::DOM_VK_ESCAPE;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Delete] = nsIDOMKeyEvent::DOM_VK_DELETE;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void glutDisplay()
|
||||
{
|
||||
if ( theApp )
|
||||
theApp->display();
|
||||
};
|
||||
/* Cursor control & motion */
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Home] = nsIDOMKeyEvent::DOM_VK_HOME;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Left] = nsIDOMKeyEvent::DOM_VK_LEFT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Up] = nsIDOMKeyEvent::DOM_VK_UP;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Right] = nsIDOMKeyEvent::DOM_VK_RIGHT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Down] = nsIDOMKeyEvent::DOM_VK_DOWN;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Page_Up] = nsIDOMKeyEvent::DOM_VK_PAGE_UP;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Page_Down] = nsIDOMKeyEvent::DOM_VK_PAGE_DOWN;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_End] = nsIDOMKeyEvent::DOM_VK_END;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void glutIdle()
|
||||
{
|
||||
if ( theApp )
|
||||
theApp->idle();
|
||||
};
|
||||
/* Misc Functions */
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Print] = nsIDOMKeyEvent::DOM_VK_PRINTSCREEN;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Insert] = nsIDOMKeyEvent::DOM_VK_INSERT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Cancel] = nsIDOMKeyEvent::DOM_VK_CANCEL;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Num_Lock] = nsIDOMKeyEvent::DOM_VK_NUM_LOCK;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void glutKeyboard( unsigned char keyIn, int xIn, int yIn )
|
||||
{
|
||||
if ( keyIn == 27 )
|
||||
{
|
||||
if ( theApp )
|
||||
theApp->reset();
|
||||
/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Space] = nsIDOMKeyEvent::DOM_VK_SPACE;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Tab] = nsIDOMKeyEvent::DOM_VK_TAB;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Enter] = nsIDOMKeyEvent::DOM_VK_ENTER;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Home] = nsIDOMKeyEvent::DOM_VK_HOME;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Left] = nsIDOMKeyEvent::DOM_VK_LEFT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Up] = nsIDOMKeyEvent::DOM_VK_UP;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Right] = nsIDOMKeyEvent::DOM_VK_RIGHT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Down] = nsIDOMKeyEvent::DOM_VK_DOWN;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Page_Up] = nsIDOMKeyEvent::DOM_VK_PAGE_UP;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Page_Down] = nsIDOMKeyEvent::DOM_VK_PAGE_DOWN;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_End] = nsIDOMKeyEvent::DOM_VK_END;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Insert] = nsIDOMKeyEvent::DOM_VK_INSERT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Delete] = nsIDOMKeyEvent::DOM_VK_DELETE;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Equal] = nsIDOMKeyEvent::DOM_VK_EQUALS;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Multiply] = nsIDOMKeyEvent::DOM_VK_MULTIPLY;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Add] = nsIDOMKeyEvent::DOM_VK_ADD;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Separator] = nsIDOMKeyEvent::DOM_VK_SEPARATOR;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Subtract] = nsIDOMKeyEvent::DOM_VK_SUBTRACT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Decimal] = nsIDOMKeyEvent::DOM_VK_DECIMAL;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Divide] = nsIDOMKeyEvent::DOM_VK_DIVIDE;
|
||||
|
||||
exit( 0 );
|
||||
};
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_0] = nsIDOMKeyEvent::DOM_VK_NUMPAD0;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_1] = nsIDOMKeyEvent::DOM_VK_NUMPAD1;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_2] = nsIDOMKeyEvent::DOM_VK_NUMPAD2;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_3] = nsIDOMKeyEvent::DOM_VK_NUMPAD3;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_4] = nsIDOMKeyEvent::DOM_VK_NUMPAD4;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_5] = nsIDOMKeyEvent::DOM_VK_NUMPAD5;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_6] = nsIDOMKeyEvent::DOM_VK_NUMPAD6;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_7] = nsIDOMKeyEvent::DOM_VK_NUMPAD7;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_8] = nsIDOMKeyEvent::DOM_VK_NUMPAD8;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_9] = nsIDOMKeyEvent::DOM_VK_NUMPAD9;
|
||||
|
||||
if ( theApp )
|
||||
theApp->keyboard( keyIn, xIn, yIn );
|
||||
};
|
||||
/*
|
||||
* Auxiliary Functions; note the duplicate definitions for left and right
|
||||
* function keys; Sun keyboards and a few other manufactures have such
|
||||
* function key groups on the left and/or right sides of the keyboard.
|
||||
* We've not found a keyboard with more than 35 function keys total.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void glutMouseMove( int xIn , int yIn )
|
||||
{
|
||||
if ( theApp )
|
||||
theApp->mouseMove( xIn, yIn );
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F1] = nsIDOMKeyEvent::DOM_VK_F1;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F2] = nsIDOMKeyEvent::DOM_VK_F2;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F3] = nsIDOMKeyEvent::DOM_VK_F3;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F4] = nsIDOMKeyEvent::DOM_VK_F4;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F5] = nsIDOMKeyEvent::DOM_VK_F5;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F6] = nsIDOMKeyEvent::DOM_VK_F6;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F7] = nsIDOMKeyEvent::DOM_VK_F7;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F8] = nsIDOMKeyEvent::DOM_VK_F8;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F9] = nsIDOMKeyEvent::DOM_VK_F9;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F10] = nsIDOMKeyEvent::DOM_VK_F10;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F11] = nsIDOMKeyEvent::DOM_VK_F12;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F12] = nsIDOMKeyEvent::DOM_VK_F13;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F13] = nsIDOMKeyEvent::DOM_VK_F13;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F14] = nsIDOMKeyEvent::DOM_VK_F14;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F15] = nsIDOMKeyEvent::DOM_VK_F15;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F16] = nsIDOMKeyEvent::DOM_VK_F16;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F17] = nsIDOMKeyEvent::DOM_VK_F17;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F18] = nsIDOMKeyEvent::DOM_VK_F18;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F19] = nsIDOMKeyEvent::DOM_VK_F19;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F20] = nsIDOMKeyEvent::DOM_VK_F20;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F21] = nsIDOMKeyEvent::DOM_VK_F21;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F22] = nsIDOMKeyEvent::DOM_VK_F22;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F23] = nsIDOMKeyEvent::DOM_VK_F23;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F24] = nsIDOMKeyEvent::DOM_VK_F24;
|
||||
|
||||
|
||||
/* Modifiers */
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Meta_L] = nsIDOMKeyEvent::DOM_VK_META;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Meta_R] = nsIDOMKeyEvent::DOM_VK_META;
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Control_L] = nsIDOMKeyEvent::DOM_VK_CONTROL;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Control_R] = nsIDOMKeyEvent::DOM_VK_CONTROL;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Shift_L] = nsIDOMKeyEvent::DOM_VK_SHIFT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Shift_R] = nsIDOMKeyEvent::DOM_VK_SHIFT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Alt_R] = nsIDOMKeyEvent::DOM_VK_ALT;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Alt_L] = nsIDOMKeyEvent::DOM_VK_ALT;
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Caps_Lock] = nsIDOMKeyEvent::DOM_VK_CAPS_LOCK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void glutMouseButton( int buttonIn, int stateIn, int xIn, int yIn )
|
||||
int UBrowserImage::convertToXULKey(int key) const
|
||||
{
|
||||
if ( theApp )
|
||||
theApp->mouseButton( buttonIn, stateIn, xIn, yIn );
|
||||
KeyMap::const_iterator itr = _keyMap.find(key);
|
||||
if (_keyMap.find(key)==_keyMap.end()) return key;
|
||||
else return itr->second;
|
||||
|
||||
}
|
||||
|
||||
static void on_destroy(GtkWidget * widget, gpointer data) {
|
||||
gtk_main_quit ();
|
||||
osg::Node* createInteractiveQuad(const osg::Vec3& origin, osg::Vec3& widthAxis, osg::Vec3& heightAxis,
|
||||
osg::Image* image)
|
||||
{
|
||||
bool flip = image->getOrigin()==osg::Image::TOP_LEFT;
|
||||
|
||||
}
|
||||
osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(origin, widthAxis, heightAxis,
|
||||
0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f);
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D(image);
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
|
||||
texture,
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
pictureQuad->setEventCallback(new osgViewer::InteractiveImageHandler(image));
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(pictureQuad);
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
osg::ArgumentParser arguments(&argc, argv);
|
||||
|
||||
// implementation in a class so we can observer events
|
||||
// means we need this painful GLUT <--> class shim...
|
||||
theApp = new testGL;
|
||||
osgViewer::Viewer viewer(arguments);
|
||||
|
||||
if ( theApp )
|
||||
{
|
||||
glutInit( &argc, argv );
|
||||
glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
|
||||
typedef std::list< osg::ref_ptr<UBrowserImage> > Images;
|
||||
Images images;
|
||||
|
||||
glutInitWindowPosition( 80, 0 );
|
||||
glutInitWindowSize( theApp->getAppWindowWidth(), theApp->getAppWindowHeight() );
|
||||
for(int i=1; i<arguments.argc(); ++i)
|
||||
{
|
||||
if (!arguments.isOption(i))
|
||||
{
|
||||
osg::ref_ptr<UBrowserImage> browserImage= new UBrowserImage(arguments[0], 768, 1024);
|
||||
browserImage->navigateTo(arguments[i]);
|
||||
images.push_back(browserImage.get());
|
||||
}
|
||||
}
|
||||
|
||||
glutCreateWindow( theApp->getAppWindowName().c_str() );
|
||||
bool xyPlane = false;
|
||||
|
||||
theApp->init( argv[ 0 ] );
|
||||
osg::Group* group = new osg::Group;
|
||||
|
||||
glutKeyboardFunc( glutKeyboard );
|
||||
osg::Vec3 origin = osg::Vec3(0.0f,0.0f,0.0f);
|
||||
for(Images::iterator itr = images.begin();
|
||||
itr != images.end();
|
||||
++itr)
|
||||
{
|
||||
osg::Image* image = itr->get();
|
||||
float width = 1.0;
|
||||
float height = float(image->t())/float(image->s());
|
||||
|
||||
osg::Vec3 widthAxis = osg::Vec3(width,0.0f,0.0f);
|
||||
osg::Vec3 heightAxis = xyPlane ? osg::Vec3(0.0f,height,0.0f) : osg::Vec3(0.0f,0.0f,height);
|
||||
|
||||
group->addChild(createInteractiveQuad(origin, widthAxis, heightAxis, image));
|
||||
|
||||
origin += widthAxis*1.1f;
|
||||
}
|
||||
|
||||
viewer.setSceneData(group);
|
||||
|
||||
glutMouseFunc( glutMouseButton );
|
||||
glutPassiveMotionFunc( glutMouseMove );
|
||||
glutMotionFunc( glutMouseMove );
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
|
||||
|
||||
glutDisplayFunc( glutDisplay );
|
||||
glutReshapeFunc( glutReshape );
|
||||
viewer.realize();
|
||||
|
||||
while(!viewer.done())
|
||||
{
|
||||
|
||||
glutIdleFunc( glutIdle );
|
||||
#ifndef _WINDOWS
|
||||
// pump the GTK+Gecko event queue for a (limited) while. this should
|
||||
// be done so that the Gecko event queue doesn't starve, and done
|
||||
// *here* so that mNeedsUpdate[] can be populated by callbacks
|
||||
// from Gecko.
|
||||
gtk_main_iteration_do(0);
|
||||
for (int iter=0; iter<10; ++iter)
|
||||
{
|
||||
if (gtk_events_pending())
|
||||
gtk_main_iteration();
|
||||
}
|
||||
#endif
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
delete theApp;
|
||||
};
|
||||
for(Images::iterator itr = images.begin();
|
||||
itr != images.end();
|
||||
++itr)
|
||||
{
|
||||
osg::ref_ptr<UBrowserImage> browser = *(itr);
|
||||
if (browser.valid())
|
||||
{
|
||||
browser->update();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
viewer.frame();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user