Andreas posted an example of this on 11/6, which I attached. It worked
great
Alex Löffler wrote:
Hi,
I built an Linux/Qt/OpenSG 1.2.0 application that uses an
OSGQGLManagedWidget to display and manipulate a VRML scene.
What I am trying to achieve right now, is providing a switch to display the
scene in passive stereo via the two monitor ports of my graphics controller.
I am not really into OpenSG stereo and tried to handle the problem like in
the testStereoDecorator.cpp example, but the ManagedWidget did not provide
the desired functionality to add Viewports and the like ...
Is there any solution to port the scene to a QTWindow or something, that is
capable of stereo display? And which OpenSG-Qt interface is the one to
choose?
Thanks in advance for your answers.
Regards,
Alex.
-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users
--
Jack S.Gundrum
Research Programmer
Graduate Education and Research Services
Academic Services and Emerging Technologies
Information Technology Services
Penn State University
// Simple QT cluster client
// usage:
// testClusterServerQT pipe0 -g320,200,0,0
// testClusterClientQT pipe0
#include <iostream>
#include <qgl.h>
#include <qapplication.h>
#include <math.h>
#if defined(Q_CC_MSVC)
#pragma warning(disable:4305) // init: truncation from const double to float
#endif
#include <OSGConfig.h>
#include <OSGSceneFileHandler.h>
#include <OSGSimpleGeometry.h>
#include <OSGPassiveWindow.h>
#include <OSGSimpleSceneManager.h>
#include <OSGClusterWindow.h>
#include <OSGMultiDisplayWindow.h>
#include <OSGSolidBackground.h>
OSG_USING_NAMESPACE
// ClusterClientGLWidget
class ClusterClientGLWidget : public QGLWidget
{
public:
ClusterClientGLWidget( QGLFormat f, QWidget *parent=0, const char *name=0 );
virtual ~ClusterClientGLWidget();
SimpleSceneManager *getManager(void);
PassiveWindowPtr getWindow(void);
void setClusterWindow(const ClusterWindowPtr &cwin);
protected:
void initializeGL();
void resizeGL( int, int );
void paintGL();
void mousePressEvent( QMouseEvent *ev );
void mouseMoveEvent( QMouseEvent *ev );
void mouseReleaseEvent( QMouseEvent *ev );
void wheelEvent( QWheelEvent *ev );
SimpleSceneManager *_mgr;
PassiveWindowPtr _pwin;
ClusterWindowPtr _cwin;
};
ClusterClientGLWidget::ClusterClientGLWidget( QGLFormat f, QWidget *parent,
const char *name )
: QGLWidget( f, parent, name ),
_mgr(NULL),
_pwin(NullFC),
_cwin(NullFC)
{
setAutoBufferSwap(false);
_mgr = new SimpleSceneManager;
_pwin = PassiveWindow::create();
_mgr->setWindow(_pwin);
}
ClusterClientGLWidget::~ClusterClientGLWidget(void)
{
delete _mgr;
subRefCP(_pwin);
}
SimpleSceneManager *ClusterClientGLWidget::getManager(void)
{
return _mgr;
}
PassiveWindowPtr ClusterClientGLWidget::getWindow(void)
{
return _pwin;
}
void ClusterClientGLWidget::setClusterWindow(const ClusterWindowPtr &cwin)
{
_cwin = cwin;
}
void ClusterClientGLWidget::initializeGL()
{
_pwin->init();
}
void ClusterClientGLWidget::resizeGL( int width, int height )
{
_mgr->resize(width,height);
}
void ClusterClientGLWidget::paintGL()
{
// we don't need to render the client window this is already done
// in _cwin->render() but only when the client window is set via
setClientWindow()
//_mgr->redraw();
// update the camera.
_mgr->getNavigator()->updateCameraTransformation();
try
{
if(_cwin != NullFC)
_cwin->render((RenderAction *) _mgr->getAction());
Thread::getCurrentChangeList()->clearAll();
}
catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
{
std::cout << e.what() << std::endl;
exit(0);
}
swapBuffers();
}
void ClusterClientGLWidget::mousePressEvent( QMouseEvent *ev )
{
UInt32 button;
switch ( ev->button() )
{
case LeftButton: button = SimpleSceneManager::MouseLeft; break;
case MidButton: button = SimpleSceneManager::MouseMiddle; break;
case RightButton: button = SimpleSceneManager::MouseRight; break;
default: return;
}
_mgr->mouseButtonPress(button, ev->x(), ev->y());
updateGL();
}
void ClusterClientGLWidget::mouseReleaseEvent( QMouseEvent *ev )
{
UInt32 button;
switch ( ev->button() )
{
case LeftButton: button = SimpleSceneManager::MouseLeft; break;
case MidButton: button = SimpleSceneManager::MouseMiddle; break;
case RightButton: button = SimpleSceneManager::MouseRight; break;
default: return;
}
_mgr->mouseButtonRelease(button, ev->x(), ev->y());
updateGL();
}
void ClusterClientGLWidget::mouseMoveEvent( QMouseEvent *ev )
{
_mgr->mouseMove(ev->x(), ev->y());
updateGL();
}
void ClusterClientGLWidget::wheelEvent( QWheelEvent *ev )
{
_mgr->mouseButtonPress(ev->delta() > 0 ? SimpleSceneManager::MouseUp
: SimpleSceneManager::MouseDown,
ev->x(), ev->y());
ev->accept();
updateGL();
}
// -------------------
int main( int argc, char **argv )
{
ChangeList::setReadWriteDefault();
osgInit(argc,argv);
// clear changelist from prototypes
OSG::Thread::getCurrentChangeList()->clearAll();
QApplication::setColorSpec( QApplication::ManyColor );
QApplication a( argc, argv );
if ( !QGLFormat::hasOpenGL() )
{
qWarning( "This system has no OpenGL support. Exiting." );
return -1;
}
// parse command line
std::string connectionType = "StreamSock";
std::string serviceAddress;
std::vector<char *> filenames;
for(int i=1;i<argc;++i)
{
if(strlen(argv[i])>1 && argv[i][0]=='-')
{
switch(argv[i][1])
{
case 'b':
serviceAddress.assign(argv[i]+2);
break;
case 'f':
filenames.push_back(argv[i]+2);
break;
case 'm':
connectionType="Multicast";
break;
case 'h':
std::cout << "testClusterClientQT [servername]+
[-f<filename>]* [-m]? [-b]? [-h]?"
<< std::endl;
std::cout << "-m use multicast" << std::endl;
std::cout << "-b service address" << std::endl;
std::cout << "-h help" << std::endl << std::endl;
std::cout << "e.g. testClusterClientQT pipe0 -ftie.wrl" <<
std::endl << std::endl;
return 0;
}
}
}
ClusterClientGLWidget w(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer |
QGL::Rgba |
QGL::DirectRendering));
// create the scene
NodePtr scene = Node::create();
GroupPtr g = Group::create();
beginEditCP(scene);
scene->setCore(g);
endEditCP(scene);
if(!filenames.empty())
{
beginEditCP(scene);
for(int i = 0; i < filenames.size(); ++i)
{
NodePtr file = SceneFileHandler::the().read(filenames[i]);
if(file != NullFC);
scene->addChild(file);
}
endEditCP(scene);
}
if(scene->getNChildren() == 0)
{
scene = makeTorus(.5, 3, 16, 16);
}
w.getManager()->setRoot(scene);
w.getManager()->showAll();
a.setMainWidget( &w );
ViewportPtr clientvp = w.getWindow()->getPort()[0];
// create the viewports for the cluster just a simple one ...
ViewportPtr vp1 = Viewport::create();
beginEditCP(vp1);
vp1->setCamera (w.getManager()->getCamera());
vp1->setBackground(clientvp->getBackground());
vp1->setRoot (clientvp->getRoot());
vp1->setSize (0,0, 1,1);
endEditCP(vp1);
// create multi display cluster window
int rows = 1;
MultiDisplayWindowPtr clusterWindow = MultiDisplayWindow::create();
beginEditCP(clusterWindow);
// set servers
for(int i=1;i<argc;i++)
{
if(argv[i][0]!='-' &&
(argv[i][0]<'0' || argv[i][0]>'9'))
{
clusterWindow->getServers().push_back(argv[i]);
}
}
clusterWindow->setHServers(clusterWindow->getServers().size()/rows);
clusterWindow->setVServers(rows);
clusterWindow->setInterleave(0);
clusterWindow->setConnectionType(connectionType);
clusterWindow->setSize(w.width(), w.height());
clusterWindow->addPort(vp1);
if(!serviceAddress.empty())
clusterWindow->setServiceAddress(serviceAddress);
clusterWindow->setClientWindow(w.getWindow());
endEditCP(clusterWindow);
clusterWindow->init();
w.setClusterWindow(clusterWindow);
w.show();
w.updateGL();
bool r = 0;
try
{
r = a.exec();
}
catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
{
SLOG << e.what() << std::endl;
}
w.setClusterWindow(NullFC);
subRefCP(clusterWindow);
return r;
}
// Simple QT cluster server.
// usage:
// testClusterServerQT pipe0 -g320,200,0,0
// testClusterClientQT pipe0
#include <OSGConfig.h>
#include <stdlib.h>
#include <string>
#include <qapplication.h>
#include <qwidget.h>
#include <qimage.h>
#include <qpixmap.h>
#include <qbitmap.h>
#include <qfile.h>
#include <qlabel.h>
#include <qregion.h>
#include <qpushbutton.h>
#include <qstring.h>
#include <qevent.h>
#include <qnetwork.h>
#include <qstylefactory.h>
#include <qlibrary.h>
#include <qstring.h>
#include <qprocess.h>
#include <qcursor.h>
#include <qgl.h>
#include "OSGBaseFunctions.h"
#include "OSGNode.h"
#include <OSGLog.h>
#include <OSGStreamSockConnection.h>
#include <OSGClusterServer.h>
#include <OSGRenderAction.h>
#include <OSGOSGWriter.h>
#include <OSGViewport.h>
#include <OSGWindow.h>
#include <OSGPassiveWindow.h>
#include <OSGRenderAction.h>
OSG_USING_NAMESPACE
static bool _exit_app = false;
// cluster qt render widget
class ClusterServerGLWidget : public QGLWidget
{
public:
ClusterServerGLWidget(const QGLFormat &format, QWidget *parent = 0, const
char *name = 0, WFlags f = 0);
virtual ~ClusterServerGLWidget(void);
void setServer(ClusterServer *server);
PassiveWindowPtr getWindow(void);
RenderAction *getRenderAction(void);
bool isInitialized(void);
protected:
virtual void initializeGL(void);
virtual void paintGL(void);
virtual void resizeGL(int w, int h);
virtual void keyPressEvent(QKeyEvent *e);
private:
PassiveWindowPtr _window;
RenderAction *_ract;
ClusterServer *_server;
bool _initialized;
};
ClusterServerGLWidget::ClusterServerGLWidget(const QGLFormat &format, QWidget
*parent, const char *name , WFlags f) :
QGLWidget(format , parent, name, 0, f),
_window(NullFC),
_ract(NULL),
_server(NULL),
_initialized(false)
{
setAutoBufferSwap(false);
setCursor(QCursor(QCursor::BlankCursor));
_ract = RenderAction::create();
_ract->setSortTrans(true);
_ract->setZWriteTrans(true);
_window = PassiveWindow::create();
setFocus();
}
ClusterServerGLWidget::~ClusterServerGLWidget(void)
{
// Destroys the QTWindow and its gl context!
subRefCP(_window);
}
void ClusterServerGLWidget::setServer(ClusterServer *server)
{
_server = server;
}
PassiveWindowPtr ClusterServerGLWidget::getWindow(void)
{
return _window;
}
RenderAction *ClusterServerGLWidget::getRenderAction(void)
{
return _ract;
}
bool ClusterServerGLWidget::isInitialized(void)
{
return _initialized;
}
void ClusterServerGLWidget::initializeGL(void)
{
_window->init();
makeCurrent();
_window->activate(); // and activate it
// some manual init, will be moved into StateChunks later
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_initialized = true;
}
void ClusterServerGLWidget::paintGL(void)
{
if(_server == NULL)
return;
makeCurrent();
//_window->frameInit();
_server->render(_ract);
swapBuffers();
//_window->frameExit();
Thread::getCurrentChangeList()->clearAll();
}
void ClusterServerGLWidget::resizeGL(int w, int h)
{
if(!_window->isResizePending())
{
_window->resize(w, h);
_window->resizeGL();
}
}
void ClusterServerGLWidget::keyPressEvent(QKeyEvent *e)
{
if(e->key() == Qt::Key_Q)
{
_exit_app = true;
}
}
// --------------------------------
int main(int argc, char **argv)
{
ClusterServer *server = NULL;
ClusterServerGLWidget *window = NULL;
UInt32 servicePort=8437;
std::string serviceGroup="224.245.211.234";
bool running = false;
bool exitOnError = false;
// QT init
QApplication::setColorSpec(QApplication::ManyColor);
QApplication *app = new QApplication(argc, argv);
if(!QGLFormat::hasOpenGL())
{
qWarning("This system has no OpenGL support. Exiting.");
return -1;
}
app->connect(app, SIGNAL(lastWindowClosed()), app, SLOT(quit()));
// init OSG
ChangeList::setReadWriteDefault();
osgLog().setLogLevel(LOG_WARNING);
osgInit(argc, argv);
char *name = "ClusterServer";
char *connectionType = "StreamSock";
bool noborder = true;
std::string address = "";
int width=-1,height=300,x=0,y=0;
bool stereobuffer = false;
for(int i=1;i<argc;i++)
{
if(strlen(argv[i])>1 && argv[i][0]=='-')
{
switch(argv[i][1])
{
case 'm':
connectionType="Multicast";
break;
case 'w':
noborder = false;
break;
case 'e':
exitOnError=true;
break;
case 'a':
address=&(argv[i][2]);
break;
case 'g':
if(sscanf(&(argv[i][2]),"%d,%d,%d,%d",
&width,&height,&x,&y)!=4)
{
SWARNING << "Wrong args in -g. Use -gw,h,x,y"
<< std::endl;
exit(0);
}
break;
case 'p':
if(argv[i][2] != '\0')
servicePort=atoi(argv[i]+2);
else
servicePort=atoi(argv[++i]);
break;
case 'j':
if(argv[i][2] != '\0')
serviceGroup=argv[i]+2;
else
serviceGroup=argv[++i];
break;
case 's':
stereobuffer = true;
break;
case 'h':
std::cout << "testClusterServerQT "
<< "-m "
<< "-w "
<< "-e "
<< "-gw,h,x,y "
<< "-aAddress "
<< "-j group "
<< "-p servicePort "
<< std::endl;
std::cout << "-m use multicast" << std::endl;
std::cout << "-w enables window border" << std::endl;
std::cout << "-e exit after closed connection"
<< std::endl;
std::cout << "-g geometry" << std::endl;
std::cout << "-a Address Server network address"
<< std::endl;
std::cout << "-s active stereo" << std::endl;
return 0;
}
}
else
name=argv[i];
}
try
{
if(stereobuffer)
{
window = new ClusterServerGLWidget(QGLFormat(QGL::DirectRendering |
QGL::DoubleBuffer |
QGL::DepthBuffer | QGL::Rgba |
QGL::StereoBuffers),
NULL, "ClusterRender", noborder ?
QWidget::WStyle_Customize | QWidget::WStyle_NoBorder |
QWidget::WStyle_StaysOnTop : 0);
}
else
{
window = new ClusterServerGLWidget(QGLFormat(QGL::DirectRendering |
QGL::DoubleBuffer |
QGL::DepthBuffer | QGL::Rgba),
NULL, "ClusterRender",
noborder ?
QWidget::WStyle_Customize | QWidget::WStyle_NoBorder |
QWidget::WStyle_StaysOnTop : 0);
}
if(stereobuffer && !window->format().stereo())
SWARNING << "OpenGL stereo is not available!" << std::endl;
if(width == -1)// fullscreen
{
const QRect screen =
qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(window));
x = screen.topLeft().x();
y = screen.topLeft().y();
width = screen.size().width();
height = screen.size().height();
}
server = new ClusterServer(window->getWindow(), name,
connectionType, address,
servicePort, serviceGroup);
window->setServer(server);
server->start();
running=true;
window->move(x, y);
window->resize(width, height);
window->raise();
window->show();
// needed for the XServer!
window->move(x, y);
window->show();
window->raise();
_exit_app = false;
while(!_exit_app)
{
if(!running)
{
server->start();
running=true;
window->show();
window->raise();
}
app->processEvents(0);
try
{
window->updateGL();
}
catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
{
if(exitOnError)
{
SLOG << e.what() << std::endl;
try
{
delete server;
}
catch(...)
{
}
osgExit();
exit(0);
}
else
{
// try to restart server
try
{
server->stop();
}
catch(...)
{
}
running=false;
window->hide();
}
}
}
}
catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
{
SLOG << e.what() << std::endl;
delete server;
osgExit();
return 0;
}
delete server;
osgExit();
return 0;
}