root/branches/Dirk_CPtr/Tutorials/12ClusterServerX.cpp

Revision 619, 11.4 kB (checked in by dirk, 2 years ago)

Added support for local libs for individual Tuts
Added Cluster tuts (thanks to Patrick hartling!)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
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.
9 //
10 // Libs: Cluster WindowX
11
12 #ifndef WIN32
13
14 #include <iostream>
15
16 // General OpenSG configuration, needed everywhere
17 #include <OpenSG/OSGConfig.h>
18 // The Cluster server definition
19 #include <OpenSG/OSGClusterServer.h>
20 // The GLUT-OpenSG connection class
21 #include <OpenSG/OSGXWindow.h>
22 // Render action definition.
23 #include <OpenSG/OSGRenderAction.h>
24
25 OSG_USING_NAMESPACE
26
27 // local glut window
28 XWindowPtr   window;
29 // render action
30 RenderAction   *ract;
31 // pointer the the cluster server instance
32 ClusterServer  *server;
33 bool            exitOnError = false;
34
35 // forward declaration so we can have the interesting stuff upfront
36 void display();
37 void reshape( int width, int height );
38
39 int wait_for_map_notify(Display *, XEvent *event, char *arg)
40 {
41     return( event->type == MapNotify && event->xmap.window == (::Window)arg );
42 }
43
44 // Initialize GLUT & OpenSG and start the cluster server
45 int main(int argc,char **argv)
46 {
47     int             winid;
48     char           *name           = "ClusterServer";
49     char           *connectionType = "StreamSock";
50     bool            fullscreen     = true;
51     std::string     address        = "";
52     char           *opt;
53     bool            doStereo       = false;
54     UInt32          servicePort    = 8437;
55     std::string     serviceGroup   = "224.245.211.234";
56
57
58     // evaluate params
59     for(int a=1 ; a<argc ; ++a)
60     {
61         if(argv[a][0] == '-')
62         {
63             switch(argv[a][1])
64             {
65                 case 'm':
66                     connectionType="Multicast";
67                           break;
68
69                 case 's':
70                     doStereo=true;
71                     break;
72
73                 case 'w':
74                     fullscreen=false;
75                     break;
76
77                 case 'e':
78                     exitOnError=true;
79                     break;
80
81                 case 'a': address = argv[a][2] ? argv[a]+2 : argv[++a];
82                           if(address == argv[argc])
83                           {
84                               SLOG << "address missing" << endLog;
85                               return 0;
86                           }
87                           std::cout << address << endLog;
88                           break;
89
90
91                 case 'p':
92                     if(argv[a][2] != '\0')
93                         servicePort=atoi(argv[a]+2);
94                     else
95                         servicePort=atoi(argv[++a]);
96                     break;
97
98                 case 'j':
99                     if(argv[a][2] != '\0')
100                         serviceGroup=argv[a]+2;
101                     else
102                         serviceGroup=argv[++a];
103                     break;
104              
105                 case 'h':
106                 default
107                     std::cout << argv[0]
108                               << "-m "
109                               << "-s "
110                               << "-w "
111                               << "-e "
112                               << "-a Address "
113                               << "-j group "
114                               << "-p servicePort "
115                               << std::endl;
116                     std::cout << "-m         use multicast" << std::endl;
117                     std::cout << "-s         enable stereo" << std::endl;
118                     std::cout << "-w         no fullscreen" << std::endl;
119                     std::cout << "-e         exit after closed connection"
120                               << std::endl;
121                     std::cout << "-a Address Server network address"
122                               << std::endl;
123                     std::cout << "-m Address wait for requests on "
124                               << "multicast group" << std::endl;
125                     std::cout << "-p port    wait for requests on port"
126                               << std::endl;
127                     return 0;
128             }
129         }
130         else
131         {
132             name=argv[a];
133         }
134     }
135     try
136     {
137         // init OpenSG
138         osgInit(argc, argv);
139
140         int snglBuf[] = {GLX_RGBA,
141                          GLX_DEPTH_SIZE, 16,
142                          None};
143        
144         int dblBuf[16];
145
146         dblBuf[0] = GLX_RGBA;
147         dblBuf[1] = GLX_DEPTH_SIZE;
148         dblBuf[2] = 16;
149         dblBuf[3] = GLX_DOUBLEBUFFER;
150         dblBuf[4] = (doStereo == true) ? GLX_STEREO : None;
151         dblBuf[5] = None;
152
153         GLboolean doubleBuffer = GL_FALSE;
154
155         // X init
156         DisplayP dpy = XOpenDisplay(NULL);
157
158         if(dpy == NULL)
159         {
160             std::cerr << "Error: Could not open display!" << std::endl;
161         }
162
163         int dummy;
164
165         if(!glXQueryExtension( dpy, &dummy, &dummy))
166         {
167             std::cerr << "Error: X server has no OpenGL GLX extension"
168                       << std::endl;
169         }
170        
171         XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
172
173         if(vi == NULL)
174         {
175             vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
176
177             if(vi == NULL)
178             {
179                 std::cerr << "no RGB visual with depth buffer" << std::endl;
180             }
181            
182             doubleBuffer = GL_FALSE;
183         }
184
185         if(vi->c_class != TrueColor)
186         {
187             std::cerr << "TrueColor visual required for this program"
188                       << std::endl;
189         }
190        
191         Colormap cmap = XCreateColormap(dpy,
192                                         RootWindow(dpy, vi->screen),
193                                         vi->visual,
194                                         AllocNone);
195         XSetWindowAttributes swa;
196
197         swa.colormap = cmap;
198         swa.border_pixel = 0;
199         swa.event_mask =
200             ExposureMask      |
201             ButtonPressMask   |
202             ButtonReleaseMask |
203             KeyPressMask      |
204             Button1MotionMask |
205             Button2MotionMask |
206             Button3MotionMask |
207             StructureNotifyMask;
208        
209         // Create Window
210         
211         // Create a Window and connect it to the main display dpy
212         X11Window hwin = XCreateWindow(dpy,
213                                        RootWindow(dpy, vi->screen),
214                                        0, 0, 300, 300,
215                                        0,
216                                        vi->depth,
217                                        InputOutput,
218                                        vi->visual,
219                                        CWBorderPixel |
220                                        CWColormap    |
221                                        CWEventMask,
222                                        &swa );
223        
224         XSetStandardProperties(dpy, hwin, "testWindowX", "testWindowX",
225                                None, argv, argc, NULL);
226        
227         if(fullscreen == true)
228         {
229             Atom noDecorAtom = XInternAtom(dpy,
230                                            "_MOTIF_WM_HINTS",
231                                            0);
232            
233             if(noDecorAtom == None)
234             {
235                 fprintf(stderr,
236                         "Could not intern X atom for _MOTIF_WM_HINTS.\n");
237             }
238            
239             struct NoDecorHints
240             {
241                 long flags;
242                 long functions;
243                 long decorations;
244                 long input_mode;
245             };
246            
247             NoDecorHints oHints;
248            
249             oHints.flags = 2;
250             oHints.decorations = 0;
251            
252             XChangeProperty(dpy,
253                             hwin,
254                             noDecorAtom,
255                             noDecorAtom,
256                             32,
257                             PropModeReplace,
258                             (unsigned char *) &oHints, 4);
259
260         }
261        
262
263         // create the render action
264         ract=RenderAction::create();
265
266         // setup the OpenSG Glut window
267         window     = XWindow::create();
268         window->setDisplay ( dpy );
269         window->setWindow ( hwin );   
270         window->init();
271  
272         XEvent        event;
273
274         XMapWindow(dpy, hwin);
275         XIfEvent(dpy, &event, wait_for_map_notify, (char *)hwin);
276
277         if(fullscreen == true)
278         {
279             XMoveWindow  (dpy, hwin, 0, 0);
280             XResizeWindow(dpy, hwin,
281                           DisplayWidth (dpy, vi->screen),
282                           DisplayHeight(dpy, vi->screen));
283
284             static char data[1] = {0};
285
286             Cursor cursor;
287             Pixmap blank;
288             XColor dummyCol;
289            
290             blank = XCreateBitmapFromData(dpy,
291                                           hwin,
292                                           data, 1, 1);
293
294             cursor = XCreatePixmapCursor(dpy,
295                                          blank,
296                                          blank,
297                                          &dummyCol, &dummyCol, 0, 0);
298
299             XFreePixmap(dpy, blank);
300
301             XDefineCursor(dpy,
302                           hwin,
303                           cursor);
304             XFlush(dpy);
305         }
306
307         window->activate();
308        
309         glEnable( GL_LIGHTING );
310         glEnable( GL_LIGHT0 );
311         glEnable( GL_NORMALIZE );
312
313         // create the cluster server
314         server     = new ClusterServer(window,name,connectionType,address);
315         // start the server
316         server->start();
317
318         Real32 w,h,a,b,c,d;
319         bool   stopIt = false;
320         int ip;
321
322         while(!stopIt)
323         {
324             while(ip = XPending(dpy))
325             {
326                 XNextEvent(dpy, &event);
327
328                 switch (event.type)
329                 {
330                     case ConfigureNotify:
331                     {
332                         reshape(event.xconfigure.width,
333                                 event.xconfigure.height);
334                     }                                                   
335                     break;
336
337                     case Expose:
338                         display();
339                         break;
340
341                 }
342                
343             }
344
345             display();
346         }   
347     }
348     catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
349     {
350         SLOG << e.what() << endLog;
351         delete server;
352         osgExit();
353     }
354     return 0;
355 }
356
357 /* render loop */
358 void display()
359 {
360     try
361     {
362         // receive scenegraph and do rendering
363         server->render(ract);
364         // clear changelist
365         OSG::Thread::getCurrentChangeList()->clear();
366     }
367     catch(OSG_STDEXCEPTION_NAMESPACE::exception &e)
368     {
369         if(exitOnError)
370         {
371             SLOG << e.what() << std::endl;
372             try
373             {
374                 delete server;
375             }
376             catch(...)
377             {
378             }
379             printf("Exit on error %s",e.what());
380             osgExit();
381             exit(0);
382         }
383         else
384         {
385             SLOG << e.what() << endLog;
386             // try to restart server
387             server->stop();
388             // start server, wait for client to connect
389             server->start();
390         }
391     }
392 }
393
394 /* window reshape */
395 void reshape( int width, int height )
396 {
397     // set new window size
398         window->resize( width, height );
399 }
400
401 #else
402
403 #include <iostream>
404
405 int main(int argc,char **argv)
406 {
407     std::cerr << "Not supported on windows platform!" << std::endl;
408 }
409 #endif // WIN32
Note: See TracBrowser for help on using the browser.