changed: gcc8 base update
[opensg.git] / Source / Contrib / ComplexSceneManager / Native-X / appClusterServerX.cpp
blob228c7db8a9c808f3f7aa2b28df62cb64e246c286
1 // OpenSG Tutorial Example: Cluster Server
2 //
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.
7 //
8 // See the ClusterClient.cpp for an example of how to use them.
10 #ifndef WIN32
12 #include <iostream>
14 #include <unistd.h>
16 #include "OSGGL.h"
17 #include <GL/glx.h>
19 // General OpenSG configuration, needed everywhere
20 #include "OSGConfig.h"
21 // The Cluster server definition
22 #include "OSGClusterServer.h"
23 // The GLUT-OpenSG connection class
24 #include "OSGXWindow.h"
25 // Render action definition.
26 #include "OSGRenderAction.h"
27 #include "OSGGeoFunctions.h"
28 #include "OSGFrameHandler.h"
30 // local glut window
31 OSG::XWindowRefPtr window = NULL;
32 // render action
33 OSG::RenderActionRefPtr ract = NULL;
34 // pointer the the cluster server instance
35 OSG::ClusterServer *server = NULL;
36 bool exitOnError = false;
37 int iCache = 0;
39 void cleanup(void)
41 window = NULL;
42 ract = NULL;
44 server->stop();
45 delete server;
47 server = NULL;
49 OSG::osgExit();
52 // forward declaration so we can have the interesting stuff upfront
53 void display(void);
54 void reshape(int width, int height);
56 int wait_for_map_notify(Display *, XEvent *event, char *arg)
58 return( (event->type == MapNotify) &&
59 (event->xmap.window == reinterpret_cast< ::Window >(arg) ) );
62 #ifdef OSG_DEBUG_OLD_C_CASTS
63 #ifdef ScreenOfDisplay
64 #undef ScreenOfDisplay
65 #endif
66 #ifdef DefaultScreen
67 #undef DefaultScreen
68 #endif
69 #define ScreenOfDisplay(dpy, scr)(&(_XPrivDisplay(dpy))->screens[scr])
70 #define DefaultScreen(dpy) ((_XPrivDisplay(dpy))->default_screen)
71 #endif
73 // Initialize GLUT & OpenSG and start the cluster server
74 int main(int argc,char **argv)
76 const char *name = "ClusterServer";
77 const char *connectionType = "StreamSock";
78 bool fullscreen = true;
79 std::string address = "";
80 bool doStereo = false;
81 std::string serviceGroup = "224.245.211.234";
82 bool noDecor = false;
84 bool geoSpec = false;
86 OSG::UInt32 width = 512;
87 OSG::UInt32 height = 512;
88 OSG::UInt32 xPos = 0;
89 OSG::UInt32 yPos = 0;
91 FILE *pOut = fopen("/tmp/cluster_server.log", "w");
93 if(pOut != NULL)
95 char **pVal = environ;
97 while(*pVal != NULL)
99 fprintf(pOut, "%s\n", *pVal);
101 ++pVal;
104 fclose(pOut);
107 // evaluate params
108 for(int a = 1 ; a < argc ; ++a)
110 if(argv[a][0] == '-')
112 switch(argv[a][1])
114 case 'a':
115 address = argv[a][2] ? argv[a]+2 : argv[++a];
117 if(address == argv[argc])
119 SLOG << "address missing" << OSG::endLog;
120 return 0;
123 std::cout << address << OSG::endLog;
124 break;
126 case 'd':
127 noDecor = true;
128 break;
130 case 'e':
131 exitOnError=true;
132 break;
134 case 'g':
136 int rc = 0;
138 if(argv[a][2] != '\0')
140 rc = sscanf(argv[a] + 2,
141 "%ux%u+%u+%u",
142 &width,
143 &height,
144 &xPos,
145 &yPos );
147 else
149 rc = sscanf(argv[++a],
150 "%ux%u+%u+%u",
151 &width,
152 &height,
153 &xPos,
154 &yPos );
157 if(rc == 4)
159 geoSpec = true;
162 break;
165 case 'j':
167 if(argv[a][2] != '\0')
168 serviceGroup=argv[a]+2;
169 else
170 serviceGroup=argv[++a];
171 break;
173 case 'm':
174 connectionType="Multicast";
175 break;
178 case 's':
179 doStereo=true;
180 break;
182 case 'w':
183 fullscreen = false;
184 break;
189 case 'h':
190 default:
191 std::cout << argv[0]
192 << "-m "
193 << "-s "
194 << "-w "
195 << "-e "
196 << "-a Address "
197 << "-j group "
198 << std::endl;
199 std::cout << "-m use multicast" << std::endl;
200 std::cout << "-s enable stereo" << std::endl;
201 std::cout << "-w no fullscreen" << std::endl;
202 std::cout << "-e exit after closed connection"
203 << std::endl;
204 std::cout << "-a Address Server network address"
205 << std::endl;
206 std::cout << "-m Address wait for requests on "
207 << "multicast group" << std::endl;
208 std::cout << "-p port wait for requests on port"
209 << std::endl;
210 return 0;
213 else
215 name=argv[a];
220 // init OpenSG
221 OSG::osgInit (argc, argv);
222 OSG::ClusterServer::init(argc, argv);
224 OSG::setVBOUsageOnPropertyProtos(true);
226 int snglBuf[] = {GLX_RGBA,
227 GLX_DEPTH_SIZE, 16,
228 None};
230 int dblBuf[16];
232 dblBuf[0] = GLX_RGBA;
233 dblBuf[1] = GLX_DEPTH_SIZE;
234 dblBuf[2] = 16;
235 dblBuf[3] = GLX_DOUBLEBUFFER;
236 dblBuf[4] = (doStereo == true) ? GLX_STEREO : None;
237 dblBuf[5] = None;
239 // X init
240 OSG::DisplayP dpy = XOpenDisplay(NULL);
242 if(dpy == NULL)
244 std::cerr << "Error: Could not open display!" << std::endl;
247 int dummy;
249 if(!glXQueryExtension( dpy, &dummy, &dummy))
251 std::cerr << "Error: X server has no OpenGL GLX extension"
252 << std::endl;
255 XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
257 if(vi == NULL)
259 vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
261 if(vi == NULL)
263 std::cerr << "no RGB visual with depth buffer" << std::endl;
267 if(vi->c_class != TrueColor)
269 std::cerr << "TrueColor visual required for this program"
270 << std::endl;
273 Colormap cmap = XCreateColormap(dpy,
274 RootWindow(dpy, vi->screen),
275 vi->visual,
276 AllocNone);
277 XSetWindowAttributes swa;
279 swa.colormap = cmap;
280 swa.border_pixel = 0;
281 swa.event_mask =
282 ExposureMask |
283 ButtonPressMask |
284 ButtonReleaseMask |
285 KeyPressMask |
286 Button1MotionMask |
287 Button2MotionMask |
288 Button3MotionMask |
289 StructureNotifyMask;
291 // Create Window
293 // Create a Window and connect it to the main display dpy
294 OSG::X11Window hwin = XCreateWindow(dpy,
295 RootWindow(dpy, vi->screen),
296 0, 0, 300, 300,
298 vi->depth,
299 InputOutput,
300 vi->visual,
301 CWBorderPixel |
302 CWColormap |
303 CWEventMask,
304 &swa );
306 XSetStandardProperties(dpy, hwin, "testWindowX", "testWindowX",
307 None, argv, argc, NULL);
309 if(fullscreen == true || noDecor == true)
311 Atom noDecorAtom = XInternAtom(dpy,
312 "_MOTIF_WM_HINTS",
315 if(noDecorAtom == None)
317 fprintf(stderr,
318 "Could not intern X atom for _MOTIF_WM_HINTS.\n");
321 struct NoDecorHints
323 long flags;
324 long functions;
325 long decorations;
326 long input_mode;
329 NoDecorHints oHints;
331 oHints.flags = 2;
332 oHints.decorations = 0;
334 XChangeProperty(dpy,
335 hwin,
336 noDecorAtom,
337 noDecorAtom,
339 PropModeReplace,
340 reinterpret_cast<unsigned char *>(&oHints), 4);
344 XStoreName(dpy, hwin, name);
346 // create the render action
347 ract = OSG::RenderAction::create();
349 // setup the OpenSG Glut window
350 window = OSG::XWindow::create();
352 window->setDisplay(dpy );
353 window->setWindow (hwin);
355 window->init();
357 XEvent event;
359 XMapWindow(dpy, hwin);
360 XIfEvent( dpy,
361 &event,
362 wait_for_map_notify,
363 reinterpret_cast<char *>(hwin));
365 if(fullscreen == true)
367 XMoveWindow (dpy, hwin, 0, 0);
368 XResizeWindow(dpy, hwin,
369 DisplayWidth (dpy, vi->screen),
370 DisplayHeight(dpy, vi->screen));
372 static char data[1] = {0};
374 Cursor cursor;
375 Pixmap blank;
376 XColor dummyCol;
378 blank = XCreateBitmapFromData(dpy,
379 hwin,
380 data, 1, 1);
382 cursor = XCreatePixmapCursor(dpy,
383 blank,
384 blank,
385 &dummyCol, &dummyCol, 0, 0);
387 XFreePixmap(dpy, blank);
389 XDefineCursor(dpy,
390 hwin,
391 cursor);
392 XFlush(dpy);
394 else if(geoSpec == true)
396 XMoveResizeWindow(dpy,
397 hwin,
398 xPos,
399 yPos,
400 width,
401 height);
404 window->activate();
406 glEnable(GL_LIGHTING );
407 glEnable(GL_LIGHT0 );
408 glEnable(GL_NORMALIZE);
410 // create the cluster server
411 server = new OSG::ClusterServer(window,
412 name,
413 connectionType,
414 address );
415 // start the server
416 server->start();
418 bool stopIt = false;
419 int ip;
421 // OSG::FieldContainerFactory::the()->dump();
423 while(!stopIt)
425 while((ip = XPending(dpy)) != 0)
427 XNextEvent(dpy, &event);
429 switch (event.type)
431 case ConfigureNotify:
433 reshape(event.xconfigure.width,
434 event.xconfigure.height);
436 break;
438 case Expose:
439 display();
440 break;
446 display();
450 catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
452 SLOG << e.what() << OSG::endLog;
453 cleanup();
454 OSG::osgExit();
457 return 0;
460 /* render loop */
461 void display(void)
465 if(iCache < 5)
467 // fprintf(stderr, "cache %d\n", iCache);
469 ract->setFrustumCulling(false);
472 OSG::FrameHandler::the()->frame();
474 // receive scenegraph and do rendering
475 server->render(ract);
477 if(iCache < 5)
479 ract->setFrustumCulling(false);
480 ++iCache;
484 // clear changelist
485 OSG::Thread::getCurrentChangeList()->clear();
488 catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
490 if(exitOnError)
492 SLOG << e.what() << std::endl;
494 printf("Exit on error %s",e.what());
498 cleanup();
500 catch(...)
504 exit(0);
506 else
508 SLOG << e.what() << OSG::endLog;
509 // try to restart server
510 server->stop();
512 ract = OSG::RenderAction::create();
514 // start server, wait for client to connect
515 server->start();
520 /* window reshape */
521 void reshape( int width, int height )
523 // set new window size
524 window->resize( width, height );
527 #else
529 #include <iostream>
531 int main(int argc,char **argv)
533 std::cerr << "Not supported on windows platform!" << std::endl;
536 #endif // WIN32