1 // OpenSG Tutorial Example: Cluster Server
3 // This is a full functional OpenSG cluster server. In OpenSG
4 // the terms server and client are used similar to X11. The
5 // application is the client. Instances that are used for
6 // rendering are called server.
8 // See the clusterclient.cpp for an example of how to use them.
10 // Libs: Cluster WindowX
14 #ifdef OSG_BUILD_ACTIVE
15 // General OpenSG configuration, needed everywhere
16 #include <OSGConfig.h>
19 // General OpenSG configuration, needed everywhere
20 #include <OpenSG/OSGConfig.h>
21 #include <OpenSG/OSGGL.h>
27 #ifdef OSG_BUILD_ACTIVE
28 // The Cluster server definition
29 #include <OSGClusterServer.h>
30 // The GLUT-OpenSG connection class
31 #include <OSGXWindow.h>
32 // Render action definition.
33 #include <OSGRenderAction.h>
35 // The Cluster server definition
36 #include <OpenSG/OSGClusterServer.h>
37 // The GLUT-OpenSG connection class
38 #include <OpenSG/OSGXWindow.h>
39 // Render action definition.
40 #include <OpenSG/OSGRenderAction.h>
43 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
44 // CDash balks even if they're just warnings... :(
45 #pragma GCC diagnostic ignored "-Wold-style-cast"
49 OSG::XWindowRefPtr window
;
51 OSG::RenderActionRefPtr ract
= NULL
;
52 // pointer the the cluster server instance
53 OSG::ClusterServer
*server
= NULL
;
54 bool exitOnError
= false;
56 // forward declaration so we can have the interesting stuff upfront
58 void reshape( int width
, int height
);
60 int wait_for_map_notify(Display
*, XEvent
*event
, char *arg
)
62 return( event
->type
== MapNotify
&&
63 event
->xmap
.window
== ::Window(arg
));
66 // Initialize GLUT & OpenSG and start the cluster server
67 int main(int argc
,char **argv
)
69 const char *name
= "ClusterServer";
70 const char *connectionType
= "StreamSock";
71 bool fullscreen
= true;
72 std::string address
= "";
73 bool doStereo
= false;
74 std::string serviceGroup
= "224.245.211.234";
78 for(int a
=1 ; a
<argc
; ++a
)
85 connectionType
="Multicast";
100 case 'a': address
= argv
[a
][2] ? argv
[a
]+2 : argv
[++a
];
101 if(address
== argv
[argc
])
103 SLOG
<< "address missing" << OSG::endLog
;
106 std::cout
<< address
<< OSG::endLog
;
111 if(argv
[a
][2] != '\0')
112 serviceGroup
=argv
[a
]+2;
114 serviceGroup
=argv
[++a
];
127 std::cout
<< "-m use multicast" << std::endl
;
128 std::cout
<< "-s enable stereo" << std::endl
;
129 std::cout
<< "-w no fullscreen" << std::endl
;
130 std::cout
<< "-e exit after closed connection"
132 std::cout
<< "-a Address Server network address"
134 std::cout
<< "-m Address wait for requests on "
135 << "multicast group" << std::endl
;
136 std::cout
<< "-p port wait for requests on port"
149 OSG::osgInit(argc
, argv
);
151 int snglBuf
[] = {GLX_RGBA
,
157 dblBuf
[0] = GLX_RGBA
;
158 dblBuf
[1] = GLX_DEPTH_SIZE
;
160 dblBuf
[3] = GLX_DOUBLEBUFFER
;
161 dblBuf
[4] = (doStereo
== true) ? GLX_STEREO
: None
;
165 OSG::DisplayP dpy
= XOpenDisplay(NULL
);
169 std::cerr
<< "Error: Could not open display!" << std::endl
;
174 if(!glXQueryExtension( dpy
, &dummy
, &dummy
))
176 std::cerr
<< "Error: X server has no OpenGL GLX extension"
180 XVisualInfo
*vi
= glXChooseVisual(dpy
, DefaultScreen(dpy
), dblBuf
);
184 vi
= glXChooseVisual(dpy
, DefaultScreen(dpy
), snglBuf
);
188 std::cerr
<< "no RGB visual with depth buffer" << std::endl
;
192 if(vi
->c_class
!= TrueColor
)
194 std::cerr
<< "TrueColor visual required for this program"
198 Colormap cmap
= XCreateColormap(dpy
,
199 RootWindow(dpy
, vi
->screen
),
202 XSetWindowAttributes swa
;
205 swa
.border_pixel
= 0;
218 // Create a Window and connect it to the main display dpy
219 OSG::X11Window hwin
= XCreateWindow(dpy
,
220 RootWindow(dpy
, vi
->screen
),
231 XSetStandardProperties(dpy
, hwin
, "testWindowX", "testWindowX",
232 None
, argv
, argc
, NULL
);
234 if(fullscreen
== true)
236 Atom noDecorAtom
= XInternAtom(dpy
,
240 if(noDecorAtom
== None
)
243 "Could not intern X atom for _MOTIF_WM_HINTS.\n");
257 oHints
.decorations
= 0;
265 reinterpret_cast<unsigned char *>(&oHints
), 4);
270 // create the render action
271 ract
= OSG::RenderAction::create();
273 // setup the OpenSG Glut window
274 window
= OSG::XWindow::create();
275 window
->setDisplay ( dpy
);
276 window
->setWindow ( hwin
);
281 XMapWindow(dpy
, hwin
);
282 XIfEvent(dpy
, &event
, wait_for_map_notify
, reinterpret_cast<char *>(hwin
));
284 if(fullscreen
== true)
286 XMoveWindow (dpy
, hwin
, 0, 0);
287 XResizeWindow(dpy
, hwin
,
288 DisplayWidth (dpy
, vi
->screen
),
289 DisplayHeight(dpy
, vi
->screen
));
291 static char data
[1] = {0};
297 blank
= XCreateBitmapFromData(dpy
,
301 cursor
= XCreatePixmapCursor(dpy
,
304 &dummyCol
, &dummyCol
, 0, 0);
306 XFreePixmap(dpy
, blank
);
316 glEnable( GL_LIGHTING
);
317 glEnable( GL_LIGHT0
);
318 glEnable( GL_NORMALIZE
);
320 // create the cluster server
321 server
= new OSG::ClusterServer(window
,name
,connectionType
,address
);
330 while((ip
= XPending(dpy
)) != 0)
332 XNextEvent(dpy
, &event
);
336 case ConfigureNotify
:
338 reshape(event
.xconfigure
.width
,
339 event
.xconfigure
.height
);
354 catch(OSG_STDEXCEPTION_NAMESPACE::exception
&e
)
356 SLOG
<< e
.what() << OSG::endLog
;
372 // receive scenegraph and do rendering
373 server
->render(ract
);
375 OSG::Thread::getCurrentChangeList()->clear();
377 catch(OSG_STDEXCEPTION_NAMESPACE::exception
&e
)
381 SLOG
<< e
.what() << std::endl
;
392 printf("Exit on error %s",e
.what());
398 window
->clearPorts();
400 SLOG
<< e
.what() << OSG::endLog
;
401 // try to restart server
403 // start server, wait for client to connect
410 void reshape( int width
, int height
)
412 // set new window size
413 window
->resize( width
, height
);
420 int main(int argc
,char **argv
)
422 std::cerr
<< "Not supported on windows platform!" << std::endl
;