source: trunk/src/testing/app/VRA/src/VolumeRendererShell.cpp @ 4

Revision 4, 24.7 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/*--------------------------------------------------------------------------*/
2/* Volume Rendering Application                                             */
3/* Copyright (C) 2006-2007 Nicholas Schwarz                                 */
4/*                                                                          */
5/* This software is free software; you can redistribute it and/or modify it */
6/* under the terms of the GNU Lesser General Public License as published by */
7/* the Free Software Foundation; either Version 2.1 of the License, or      */
8/* (at your option) any later version.                                      */
9/*                                                                          */
10/* This software is distributed in the hope that it will be useful, but     */
11/* WITHOUT ANY WARRANTY; without even the implied warranty of               */
12/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser  */
13/* General Public License for more details.                                 */
14/*                                                                          */
15/* You should have received a copy of the GNU Lesser Public License along   */
16/* with this library; if not, write to the Free Software Foundation, Inc.,  */
17/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                    */
18/*--------------------------------------------------------------------------*/
19
20#include "VolumeRendererShell.h"
21
22#include "SynchronizerClient.h"
23
24/*--------------------------------------------------------------------------*/
25
26#ifdef SAGE
27
28// Define static variable for glXPBuffer
29GLXPbufferSGIX VolumeRendererShell::_glXPBuffer = 0;
30
31// Define static variable for X display
32Display* VolumeRendererShell::_xDisplay = NULL;
33
34// Define static variable for X error flag
35int VolumeRendererShell::_xErrorFlag = 0;
36
37// Define static variable for X visual info
38XVisualInfo* VolumeRendererShell::_xVisualInfo = NULL;
39
40#endif
41
42/*--------------------------------------------------------------------------*/
43
44VolumeRendererShell::VolumeRendererShell() {
45
46  // Initialize condition variable
47  pthread_cond_init(&_conditionCond, NULL);
48
49  // Initialize mutex
50  pthread_mutex_init(&_conditionMutex, NULL);
51
52}
53
54/*--------------------------------------------------------------------------*/
55
56VolumeRendererShell::~VolumeRendererShell() {
57
58  // Clean up condition variable
59  pthread_cond_destroy(&_conditionCond);
60
61  // Clean up mutex
62  pthread_mutex_destroy(&_conditionMutex);
63
64}
65
66/*--------------------------------------------------------------------------*/
67
68void VolumeRendererShell::AbortRender(bool flag) {
69
70  // Set abort flag
71  _info._abortFlag = flag;
72
73}
74
75/*--------------------------------------------------------------------------*/
76
77void VolumeRendererShell::DestroyDisplay() {
78
79#ifdef SAGE
80
81  // Clean up pbuffer
82  glXDestroyGLXPbufferSGIX(_xDisplay, _glXPBuffer);
83
84  // Clean up visual info
85  XFree(_xVisualInfo);
86
87  // Close X connection
88  XCloseDisplay(_xDisplay);
89
90#else
91 
92  // Quit SDL
93  SDL_Quit();
94
95#endif
96
97}
98
99/*--------------------------------------------------------------------------*/
100
101#ifdef SAGE
102
103int VolumeRendererShell::HandleXError(Display* display, XErrorEvent *event) {
104
105  // Set error flag
106  _xErrorFlag = 1;
107
108  // Return 0
109  return 0;
110
111}
112
113#endif
114
115/*--------------------------------------------------------------------------*/
116
117void VolumeRendererShell::Init(int width, int height, bool fullScreen,
118                               char* hostname, int port,
119                               float left, float right,
120                               float bottom, float top,
121                               int rank, int numberOfNodes) {
122
123  // Set mutex and condition variable in thread state
124  _info._conditionCond = &_conditionCond;
125  _info._conditionMutex = &_conditionMutex;
126
127  // Set display information in thread state
128  _info._displaySize[0] = width;
129  _info._displaySize[1] = height;
130  _info._fullScreenFlag = fullScreen;
131  _info._normalCoordinates[0] = left;
132  _info._normalCoordinates[1] = right;
133  _info._normalCoordinates[2] = bottom;
134  _info._normalCoordinates[3] = top;
135
136  // Set synchronization hostname and port
137  strcpy(_info._synchronizationHostname, hostname);
138  _info._synchronizationPort = port;
139
140  // Set rank and number of nodes
141  _info._rank = rank;
142  _info._numberOfNodes = numberOfNodes;
143
144  // Create thread
145  pthread_create(&_thread, NULL, VolumeRendererShell::ThreadFunction, &_info);
146
147}
148
149/*--------------------------------------------------------------------------*/
150
151void VolumeRendererShell::InitDisplay(int width, int height, bool fullScreen,
152                                      float left, float right,
153                                      float bottom, float top) {
154
155#ifdef SAGE
156
157  // GLX context
158  GLXContext glXContext;
159
160  // GLX pbuffer
161  GLXFBConfigSGIX glXFBConfig = 0;
162
163  // X screen
164  int xScreen = 0;
165
166  // Open display
167  _xDisplay = XOpenDisplay(NULL);
168  if (!_xDisplay) {
169    fprintf(stderr, "VolumeRendererShell: Could not open X display.\n");
170    return;
171  }
172
173  // Get default screen
174  xScreen = DefaultScreen(_xDisplay);
175
176  // Double buffered, with depth buffer
177  int fbAttribs[] = {
178    GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
179    GLX_DRAWABLE_TYPE_SGIX, GLX_PIXMAP_BIT_SGIX,
180    GLX_RED_SIZE, 1,
181    GLX_GREEN_SIZE, 1,
182    GLX_BLUE_SIZE, 1,
183    GLX_DEPTH_SIZE, 1,
184    GLX_DOUBLEBUFFER, 1,
185    GLX_STENCIL_SIZE, 0,
186    None
187  };
188
189  // Attributes
190  int pbAttribs[] = {
191    GLX_LARGEST_PBUFFER_SGIX, True,
192    GLX_PRESERVED_CONTENTS_SGIX, False,
193    None
194  };
195
196  // Possible configurations
197  GLXFBConfigSGIX* glXFBConfigs = NULL;
198  int numberOfGLXFBConfigs;
199 
200  // Get list of possible frame buffer configurations
201  glXFBConfigs = glXChooseFBConfigSGIX(_xDisplay, xScreen,
202                                       fbAttribs, &numberOfGLXFBConfigs);
203  if (numberOfGLXFBConfigs == 0 || !glXFBConfigs) {
204    fprintf(stderr, "VolumeRendererShell: Choosing FBConfig failed.\n");
205    XCloseDisplay(_xDisplay);
206    return;
207  }
208
209  // Create pbuffer using first config in the list that works
210  for (int i = 0 ; i < numberOfGLXFBConfigs ; i++) {
211
212    // Catch X errors with error handler
213    int (*oldHandler)(Display*, XErrorEvent*);
214    oldHandler = XSetErrorHandler(HandleXError);
215    _xErrorFlag = 0;
216
217    // Create pbuffer
218    _glXPBuffer = glXCreateGLXPbufferSGIX(_xDisplay, glXFBConfigs[i],
219                                         width, height, pbAttribs);
220
221    // Restore original X error handler
222    (void) XSetErrorHandler(oldHandler);
223
224    // Found a working configuration
225    if (!_xErrorFlag && _glXPBuffer != None) {
226      glXFBConfig = glXFBConfigs[i];
227      break;
228    }
229  }
230
231  // Clean up
232  XFree(glXFBConfigs);
233
234  // If a pbuffer couldn't be created
235  if (_glXPBuffer == None) {
236    fprintf(stderr, "VolumeRendererShell: Couldn't create pbuffer.\n");
237    XCloseDisplay(_xDisplay);
238    return;
239  }
240
241  // Get corresponding XVisualInfo
242  _xVisualInfo = glXGetVisualFromFBConfigSGIX(_xDisplay, glXFBConfig);
243  if (!_xVisualInfo) {
244    fprintf(stderr, "VolumeRendererShell: Can't get XVisualInfo.\n");
245    XCloseDisplay(_xDisplay);
246    return;
247  }
248
249  // Create GLX context
250  glXContext = glXCreateContext(_xDisplay, _xVisualInfo, NULL, True);
251  if (!glXContext) {
252    glXContext = glXCreateContext(_xDisplay, _xVisualInfo, NULL, False);
253    if (!glXContext) {
254      fprintf(stderr, "VolumeRendererShell: Couldn't create GLXContext.\n");
255      XFree(_xVisualInfo);
256      XCloseDisplay(_xDisplay);
257      return;
258    }
259  }
260
261  // Bind context to pbuffer
262  if (!glXMakeCurrent(_xDisplay, _glXPBuffer, glXContext)) {
263    fprintf(stderr, "VolumeRendererShell: glXMakeCurrent failed.\n");
264    XFree(_xVisualInfo);
265    XCloseDisplay(_xDisplay);
266    return;
267  }
268
269#else
270
271  // Initialize SDL
272  SDL_Init(SDL_INIT_VIDEO);
273 
274  // Set video mode
275  if (fullScreen == false) {
276    SDL_SetVideoMode(width,
277                     height,
278                     0,
279                     SDL_DOUBLEBUF | SDL_OPENGL);
280  }
281  else {
282   SDL_SetVideoMode(width,
283                    height,
284                    0,
285                    SDL_DOUBLEBUF | SDL_OPENGL | SDL_FULLSCREEN);
286   SDL_ShowCursor(SDL_DISABLE);
287  }
288  SDL_WM_SetCaption("Volume Renderer", NULL);
289
290#endif
291
292}
293
294/*--------------------------------------------------------------------------*/
295
296bool VolumeRendererShell::InRender() {
297
298  // Return in render flag
299  return _info._inRenderFlag;
300
301}
302
303/*--------------------------------------------------------------------------*/
304
305bool VolumeRendererShell::IsInitialized() {
306
307  // To be implemented
308  return true;
309
310}
311
312/*--------------------------------------------------------------------------*/
313 
314void VolumeRendererShell::Render() {
315
316  // Signal thread to update volume renderer and render
317  pthread_mutex_lock(&_conditionMutex);
318  _info._renderFlag = true;
319  pthread_cond_signal(&_conditionCond);
320  pthread_mutex_unlock(&_conditionMutex);
321
322}
323
324/*--------------------------------------------------------------------------*/
325
326void VolumeRendererShell::SetAxisOff() {
327
328  // Set flag
329  _info._axisOnFlag = false;
330
331  // Set update flag
332  _info._updateAxis = true;
333
334}
335
336/*--------------------------------------------------------------------------*/
337
338void VolumeRendererShell::SetAxisOn() {
339
340  // Set flag
341  _info._axisOnFlag = true;
342
343  // Set update flag
344  _info._updateAxis = true;
345
346}
347
348/*--------------------------------------------------------------------------*/
349
350void VolumeRendererShell::SetAxisPosition(float x, float y, float z) {
351
352  // Set data
353  _info._axisPosition[0] = x;
354  _info._axisPosition[1] = y;
355  _info._axisPosition[2] = z;
356
357  // Set update flag
358  _info._updateAxis = true;
359
360}
361
362/*--------------------------------------------------------------------------*/
363
364void VolumeRendererShell::SetBrickBoxOff() {
365
366  // Set flag
367  _info._brickBoxOnFlag = false;
368
369  // Set update flag
370  _info._updateBrickBox = true;
371
372}
373
374/*--------------------------------------------------------------------------*/
375
376void VolumeRendererShell::SetBrickBoxOn() {
377
378  // Set flag
379  _info._brickBoxOnFlag = true;
380
381  // Set update flag
382  _info._updateBrickBox = true;
383
384}
385
386/*--------------------------------------------------------------------------*/
387
388void VolumeRendererShell::SetBoundingBoxOff() {
389
390  // Set flag
391  _info._boundingBoxOnFlag = false;
392
393  // Set update flag
394  _info._updateBoundingBox = true;
395
396}
397
398/*--------------------------------------------------------------------------*/
399
400void VolumeRendererShell::SetBoundingBoxOn() {
401
402  // Set flag
403  _info._boundingBoxOnFlag = true;
404
405  // Set update flag
406  _info._updateBoundingBox = true;
407
408}
409
410/*--------------------------------------------------------------------------*/
411
412void VolumeRendererShell::SetData(Octree* data) {
413
414  // Set data
415  _info._data = data;
416
417  // Set default cache sizes
418  _info._ramSize = 50;
419  _info._vramSize = 10;
420
421  // Set update flag
422  _info._updateData = true;
423
424}
425
426/*--------------------------------------------------------------------------*/
427
428void VolumeRendererShell::SetData(Octree* data, int ramSize, int vramSize) {
429
430  // Set data
431  _info._data = data;
432
433  // Set cache sizes
434  _info._ramSize = ramSize;
435  _info._vramSize = vramSize;
436
437  // Set update flag
438  _info._updateData = true;
439
440}
441
442/*--------------------------------------------------------------------------*/
443
444void VolumeRendererShell::SetExitFlag() {
445
446  // Set exit flag
447  _info._exitFlag = true;
448
449  // Signal thread to update volume renderer and render
450  pthread_mutex_lock(&_conditionMutex);
451  _info._renderFlag = true;
452  pthread_cond_signal(&_conditionCond);
453  pthread_mutex_unlock(&_conditionMutex);
454
455  // Wait for thread to finish
456  pthread_join(_thread, NULL);
457
458}
459
460/*--------------------------------------------------------------------------*/
461
462void VolumeRendererShell::SetFrustum(float left, float right, float bottom,
463                                     float top, float near, float far) {
464
465  // Set frustum
466  _info._frustum[0] = left;
467  _info._frustum[1] = right;
468  _info._frustum[2] = bottom;
469  _info._frustum[3] = top;
470  _info._frustum[4] = near;
471  _info._frustum[5] = far;
472
473  // Set update flag
474  _info._updateFrustum = true;
475
476}
477
478/*--------------------------------------------------------------------------*/
479
480void VolumeRendererShell::SetMap(unsigned char* map) {
481
482  // Set map
483  _info._map = map;
484  _info._mapType = VOLUME_RENDERER_THREAD_INFO_MAP_8;
485
486  // Set update flag
487  _info._updateMap = true;
488
489}
490
491/*--------------------------------------------------------------------------*/
492
493void VolumeRendererShell::SetMap8(unsigned char* map) {
494
495  // Set map
496  _info._map = map;
497  _info._mapType = VOLUME_RENDERER_THREAD_INFO_MAP_8;
498
499  // Set update flag
500  _info._updateMap = true;
501
502}
503
504/*--------------------------------------------------------------------------*/
505
506void VolumeRendererShell::SetMap16(unsigned char* map) {
507
508  // Set map
509  _info._map = map;
510  _info._mapType = VOLUME_RENDERER_THREAD_INFO_MAP_16;
511
512  // Set update flag
513  _info._updateMap = true;
514
515}
516
517/*--------------------------------------------------------------------------*/
518
519void VolumeRendererShell::SetR(float m[16]) {
520
521  // Set rotation matrix
522  _info._R[0] = m[0];     
523  _info._R[1] = m[1];
524  _info._R[2] = m[2];
525  _info._R[3] = m[3];
526
527  _info._R[4] = m[4];
528  _info._R[5] = m[5];
529  _info._R[6] = m[6];
530  _info._R[7] = m[7];
531
532  _info._R[8] = m[8];
533  _info._R[9] = m[9];
534  _info._R[10] = m[10];
535  _info._R[11] = m[11];
536
537  _info._R[12] = m[12];
538  _info._R[13] = m[13];
539  _info._R[14] = m[14];
540  _info._R[15] = m[15];
541
542  // Set update flag
543  _info._updateR = true;
544
545}
546
547/*--------------------------------------------------------------------------*/
548
549void VolumeRendererShell::SetS(float m[16]) {
550
551  // Set scale matrix
552  _info._S[0] = m[0];     
553  _info._S[1] = m[1];
554  _info._S[2] = m[2];
555  _info._S[3] = m[3];
556
557  _info._S[4] = m[4];
558  _info._S[5] = m[5];
559  _info._S[6] = m[6];
560  _info._S[7] = m[7];
561
562  _info._S[8] = m[8];
563  _info._S[9] = m[9];
564  _info._S[10] = m[10];
565  _info._S[11] = m[11];
566
567  _info._S[12] = m[12];
568  _info._S[13] = m[13];
569  _info._S[14] = m[14];
570  _info._S[15] = m[15];
571
572  // Set update flag
573  _info._updateS = true;
574
575}
576
577/*--------------------------------------------------------------------------*/
578
579void VolumeRendererShell::SetSliceFrequency(double frequency) {
580
581  // Set slice frequency
582  _info._sliceFrequency = frequency;
583
584  // Set update flag
585  _info._updateSliceFrequency = true;
586
587}
588
589/*--------------------------------------------------------------------------*/
590
591void VolumeRendererShell::SetT(float m[16]) {
592
593  // Set translation matrix
594  _info._T[0] = m[0];     
595  _info._T[1] = m[1];
596  _info._T[2] = m[2];
597  _info._T[3] = m[3];
598
599  _info._T[4] = m[4];
600  _info._T[5] = m[5];
601  _info._T[6] = m[6];
602  _info._T[7] = m[7];
603
604  _info._T[8] = m[8];
605  _info._T[9] = m[9];
606  _info._T[10] = m[10];
607  _info._T[11] = m[11];
608
609  _info._T[12] = m[12];
610  _info._T[13] = m[13];
611  _info._T[14] = m[14];
612  _info._T[15] = m[15];
613
614  // Set update flag
615  _info._updateT = true;
616
617}
618
619/*--------------------------------------------------------------------------*/
620 
621void VolumeRendererShell::SetViewport(int x, int y, int w, int h) {
622
623  // Set viewport
624  _info._viewport[0] = x;
625  _info._viewport[1] = y;
626  _info._viewport[2] = w;
627  _info._viewport[3] = h;
628
629  // Set update flag
630  _info._updateViewport = true;
631
632}
633
634/*--------------------------------------------------------------------------*/
635
636void *VolumeRendererShell::ThreadFunction(void* ptr) {
637
638#ifdef SAGE
639
640  // Swap buffer observer class for SAGE
641  class SwapBuffers : public VolumeRendererCommand {
642
643  public:
644
645    // Constructor
646    SwapBuffers(int width, int height,
647                Display* display, GLXPbufferSGIX pbuffer,
648                char* hostname, int port,
649                float left, float right, float bottom, float top,
650                int rank, int numberOfNodes, int* level) {
651
652      // Current level
653      _level = level;
654
655      // Display variables
656      _xDisplay = display;
657      _glXPBuffer = pbuffer;     
658      _height = height;
659      _width = width;
660
661      // Initialize synchronizer
662      _synchronizerClient.Init(hostname, port);
663
664      // Setup SAGE viewport
665      _sageImageMap.left = left;
666      _sageImageMap.right = right;
667      _sageImageMap.bottom = bottom;
668      _sageImageMap.top = top;
669
670      // SAGE parameters
671      _sageConfig.init("VRA.conf");
672      _sageConfig.setAppName("VRA");
673      _sageConfig.rank = rank;
674      _sageConfig.nodeNum = numberOfNodes - 1;
675      _sageConfig.resX = _width;
676      _sageConfig.resY = _height;
677      _sageConfig.imageMap = _sageImageMap;
678      _sageConfig.pixFmt = PIXFMT_888;
679      _sageConfig.rowOrd = BOTTOM_TO_TOP;
680      _sageConfig.master = false;
681      _sageConfig.rendering = true;
682
683      // Initialize SAGE
684      _sageInf.init(_sageConfig);
685
686      // Check buffer
687      _image = NULL;
688      if (_image != NULL)
689        delete [] _image;
690
691      // Get buffer from SAGE
692      _image = (GLubyte*) _sageInf.getBuffer();
693
694    }
695
696    // Destructor
697    ~SwapBuffers() {
698     
699      // Finalize synchronizer
700      _synchronizerClient.Finalize();
701     
702    }
703
704    // Execute callback
705    bool Execute(int value) {
706
707      // Setup readback
708      glReadBuffer(GL_FRONT);
709      glPixelStorei(GL_PACK_ALIGNMENT, 1);
710
711      // Synchronize with other nodes
712      _synchronizerClient.Barrier(*_level);
713
714      // Swap buffer
715      if (value == 0) {
716        glXSwapBuffers(_xDisplay, _glXPBuffer);
717        glReadPixels(0, 0, _width, _height,
718                     GL_RGB, GL_UNSIGNED_BYTE, _image);
719        _sageInf.swapBuffer();
720        _image = (GLubyte*) _sageInf.getBuffer();
721        return true;
722      }
723
724      // Send current buffer
725      else {
726        glReadPixels(0, 0, _width, _height,
727                     GL_RGB, GL_UNSIGNED_BYTE, _image);
728        _sageInf.swapBuffer();
729        _image = (GLubyte*) _sageInf.getBuffer();
730        return false;
731      }
732
733    }
734
735  private:
736
737    // Current level
738    int* _level;
739
740    // Display variables
741    Display* _xDisplay;
742    GLXPbufferSGIX _glXPBuffer;
743    GLubyte* _image;
744    int _height;
745    int _width;
746   
747    // SAGE variables
748    sageRect _sageImageMap;
749    sail _sageInf;
750    sailConfig _sageConfig;
751
752    // Synchronizer
753    SynchronizerClient _synchronizerClient;
754
755  };
756
757#else
758
759  // Swap buffer observer class for SDL
760  class SwapBuffers : public VolumeRendererCommand {
761
762  public:
763
764    // Constructor
765    SwapBuffers(char* hostname, int port, int* level) {
766
767      // Current level
768      _level = level;
769
770      // Initialize synchronizer
771      _synchronizerClient.Init(hostname, port);
772
773    }
774
775    // Destructor
776    ~SwapBuffers() {
777 
778      // Finalize synchronizer
779      _synchronizerClient.Finalize();
780 
781    }
782
783    // Execute callback
784    virtual bool Execute(int value) {
785
786      // Synchronizer with other nodes
787      _synchronizerClient.Barrier(*_level);
788
789      // Swap buffer
790      if (value == 0) {
791        SDL_GL_SwapBuffers();
792        return true;
793      }
794
795      return false;
796
797    }
798
799  private:
800
801    // Current level
802    int* _level;
803
804    // Synchronizer
805    SynchronizerClient _synchronizerClient;
806
807  };
808
809#endif
810
811  // Progress observer class
812  class ProgressUpdate : public VolumeRendererCommand {
813  public:
814    ProgressUpdate(int* level) {
815      _level = level;
816    }
817    virtual bool Execute(int value) {
818      *_level = value;
819      return true;
820    }
821  private:
822    int* _level;
823  };
824
825  // Abort check observer class
826  class AbortCheck : public VolumeRendererCommand {
827  public:
828    AbortCheck(VolumeRendererThreadInfo* info) {
829      _info = info;
830    }
831    virtual bool Execute(int value) {
832      if (_info -> _abortFlag == true) {
833        _info -> _abortFlag = false;
834        return true;
835      }
836      return false;
837    }
838  private:
839    VolumeRendererThreadInfo* _info;
840  };
841
842  // Current level
843  int level = 0;
844
845  // Cast thread info class
846  VolumeRendererThreadInfo* info = (VolumeRendererThreadInfo*) ptr;
847
848  // Initialize display
849  InitDisplay(info -> _displaySize[0],
850              info -> _displaySize[1],
851              info -> _fullScreenFlag,
852              info -> _normalCoordinates[0],
853              info -> _normalCoordinates[1],
854              info -> _normalCoordinates[2],
855              info -> _normalCoordinates[3]);
856
857  // Initialize volume renderer
858  VolumeRenderer* renderer = new VolumeRenderer;
859  renderer -> Init();
860
861  // Abort render observer
862  VolumeRendererCommand* ac = new AbortCheck(info);
863  renderer -> SetAbortRenderObserver(ac); 
864
865  // Progress observer
866  VolumeRendererCommand* pu = new ProgressUpdate(&level);
867  renderer -> SetProgressObserver(pu); 
868
869#ifdef SAGE
870
871  // Swap buffer observer
872  VolumeRendererCommand* sb =
873    new SwapBuffers(info -> _displaySize[0],
874                    info -> _displaySize[1],
875                    _xDisplay, _glXPBuffer,
876                    info -> _synchronizationHostname,
877                    info -> _synchronizationPort,
878                    info -> _normalCoordinates[0],
879                    info -> _normalCoordinates[1],
880                    info -> _normalCoordinates[2],
881                    info -> _normalCoordinates[3],
882                    info -> _rank,
883                    info -> _numberOfNodes,
884                    &level);
885  renderer -> SetSwapBuffersObserver(sb);
886
887#else
888
889  // Swap buffer observer
890  VolumeRendererCommand* sb =
891    new SwapBuffers(info -> _synchronizationHostname,
892                    info -> _synchronizationPort,
893                    &level);
894  renderer -> SetSwapBuffersObserver(sb);
895
896#endif
897
898  // Get mutex and condition variables
899  pthread_mutex_t* conditionMutex = info -> _conditionMutex;
900  pthread_cond_t* conditionCond = info -> _conditionCond;
901
902  // Thread loop
903  while(info -> _exitFlag == false) {
904
905    // Wait on condition variable
906    pthread_mutex_lock(conditionMutex);
907    while(info -> _renderFlag == false) {
908      pthread_cond_wait(conditionCond, conditionMutex);
909    }
910    pthread_mutex_unlock(conditionMutex);
911 
912    // Check exit flag
913    if (info -> _exitFlag == true) {
914      continue;
915    }
916
917    // Check for update axis flag
918    if (info -> _updateAxis == true) {
919      if (info -> _axisOnFlag == true) {
920        renderer -> SetAxisOn();
921      }
922      else {
923        renderer -> SetAxisOff();
924      }
925      renderer -> SetAxisPosition(info -> _axisPosition[0],
926                                  info -> _axisPosition[1],
927                                  info -> _axisPosition[2]);
928      info -> _updateAxis = false;
929    }
930
931    // Check for update brick box flag
932    if (info -> _updateBrickBox == true) {
933      if (info -> _brickBoxOnFlag == true) {
934        renderer -> SetBrickBoxOn();
935      }
936      else {
937        renderer -> SetBrickBoxOff();
938      }
939    }
940
941    // Check for update bounding box flag
942    if (info -> _updateBoundingBox == true) {
943      if (info -> _boundingBoxOnFlag == true) {
944        renderer -> SetBoundingBoxOn();
945      }
946      else {
947        renderer -> SetBoundingBoxOff();
948      }
949    }
950
951    // Check for update data flag
952    if (info -> _updateData == true) {
953      renderer -> SetData(info -> _data, info -> _ramSize, info -> _vramSize);
954      info -> _updateData = false;
955    }
956
957    // Check for update frustum flag
958    if (info -> _updateFrustum == true) {
959      renderer -> SetFrustum(info -> _frustum[0], info -> _frustum[1],
960                             info -> _frustum[2], info -> _frustum[3],
961                             info -> _frustum[4], info -> _frustum[5]);
962      info -> _updateFrustum = false;
963    }
964
965    // Check for update map flag
966    if (info -> _updateMap == true) {
967      if (info -> _mapType == VOLUME_RENDERER_THREAD_INFO_MAP_8) {
968        renderer -> SetMapUnsigned8Int(info -> _map);
969      }
970      else if (info -> _mapType == VOLUME_RENDERER_THREAD_INFO_MAP_16) {
971        renderer -> SetMapUnsigned16Int(info -> _map);
972      }
973      info -> _updateMap = false;
974    }
975
976    // Check for update R flag
977    if (info -> _updateR == true) {
978      renderer -> SetR(info -> _R);
979      info -> _updateR = false;
980    }
981
982    // Check for update S flag
983    if (info -> _updateS == true) {
984      renderer -> SetS(info -> _S);
985      info -> _updateS = false;
986    }
987
988    // Check for update slice frequency flag
989    if (info -> _updateSliceFrequency == true) {
990      renderer -> SetSliceFrequency(info -> _sliceFrequency);
991      info -> _updateSliceFrequency = false;
992    }
993
994    // Check for update T flag
995    if (info -> _updateT == true) {
996      renderer -> SetT(info -> _T);
997      info -> _updateT = false;
998    }
999
1000    // Check for update viewport flag
1001    if (info -> _updateViewport == true) {
1002      renderer -> SetViewport(info -> _viewport[0], info -> _viewport[1],
1003                              info -> _viewport[2], info -> _viewport[3]);
1004      info -> _updateViewport = false;
1005    }
1006
1007    // Render
1008    info -> _inRenderFlag = true;
1009    renderer -> Render();
1010    info -> _abortFlag = false;
1011    info -> _inRenderFlag = false;
1012
1013    // Reset render flag
1014    info -> _renderFlag = false;
1015
1016  }
1017
1018  // Clean up renderer
1019  delete renderer;
1020
1021  // Clean up abort render observer
1022  delete ac;
1023
1024  // Clean up progress observer
1025  delete pu;
1026
1027  // Clean up swap buffer observer
1028  delete sb;
1029
1030  // Clean up display
1031  DestroyDisplay();
1032
1033}
1034
1035/*--------------------------------------------------------------------------*/
Note: See TracBrowser for help on using the repository browser.