Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // 27 // 27 // 28 // 28 // 29 // Andrew Walkden 7th February 1997 29 // Andrew Walkden 7th February 1997 30 // G4OpenGLXViewer : Class to provide XWindows 30 // G4OpenGLXViewer : Class to provide XWindows specific 31 // functionality for OpenGL in 31 // functionality for OpenGL in GEANT4 32 32 >> 33 #ifdef G4VIS_BUILD_OPENGLX_DRIVER >> 34 33 #include "G4OpenGLXViewer.hh" 35 #include "G4OpenGLXViewer.hh" 34 36 35 #include "G4OpenGLSceneHandler.hh" 37 #include "G4OpenGLSceneHandler.hh" 36 #include "G4OpenGLFontBaseStore.hh" 38 #include "G4OpenGLFontBaseStore.hh" 37 39 38 #include "G4VisExtent.hh" 40 #include "G4VisExtent.hh" 39 #include "G4LogicalVolume.hh" 41 #include "G4LogicalVolume.hh" 40 #include "G4VSolid.hh" 42 #include "G4VSolid.hh" 41 #include "G4Point3D.hh" 43 #include "G4Point3D.hh" 42 #include "G4Normal3D.hh" 44 #include "G4Normal3D.hh" 43 #include "G4StateManager.hh" 45 #include "G4StateManager.hh" 44 #include "G4VisManager.hh" 46 #include "G4VisManager.hh" 45 #include "G4Text.hh" 47 #include "G4Text.hh" 46 #include "G4Threading.hh" 48 #include "G4Threading.hh" 47 49 48 #include <X11/Xatom.h> 50 #include <X11/Xatom.h> 49 #include <X11/Xutil.h> 51 #include <X11/Xutil.h> 50 #include <X11/Xmu/StdCmap.h> 52 #include <X11/Xmu/StdCmap.h> 51 53 52 #include <assert.h> 54 #include <assert.h> 53 #include <sstream> 55 #include <sstream> 54 #include <chrono> 56 #include <chrono> 55 #include <thread> 57 #include <thread> 56 58 57 int G4OpenGLXViewer::snglBuf_RGBA[12] = 59 int G4OpenGLXViewer::snglBuf_RGBA[12] = 58 { GLX_RGBA, 60 { GLX_RGBA, 59 GLX_RED_SIZE, 1, 61 GLX_RED_SIZE, 1, 60 GLX_GREEN_SIZE, 1, 62 GLX_GREEN_SIZE, 1, 61 GLX_BLUE_SIZE, 1, 63 GLX_BLUE_SIZE, 1, 62 GLX_DEPTH_SIZE, 1, 64 GLX_DEPTH_SIZE, 1, 63 GLX_STENCIL_SIZE, 1, 65 GLX_STENCIL_SIZE, 1, 64 None }; 66 None }; 65 67 66 int G4OpenGLXViewer::dblBuf_RGBA[13] = 68 int G4OpenGLXViewer::dblBuf_RGBA[13] = 67 { GLX_RGBA, 69 { GLX_RGBA, 68 GLX_RED_SIZE, 1, 70 GLX_RED_SIZE, 1, 69 GLX_GREEN_SIZE, 1, 71 GLX_GREEN_SIZE, 1, 70 GLX_BLUE_SIZE, 1, 72 GLX_BLUE_SIZE, 1, 71 GLX_DOUBLEBUFFER, 73 GLX_DOUBLEBUFFER, 72 GLX_DEPTH_SIZE, 1, 74 GLX_DEPTH_SIZE, 1, 73 GLX_STENCIL_SIZE, 1, 75 GLX_STENCIL_SIZE, 1, 74 None }; 76 None }; 75 77 76 #define NewString(str) \ 78 #define NewString(str) \ 77 ((str) != 0 ? (strncpy((char*)malloc((unsign 79 ((str) != 0 ? (strncpy((char*)malloc((unsigned)strlen(str) + 1), str, (unsigned)strlen(str) + 1)) : (char*)0) 78 80 79 #define USE_DEFAULT_COLORMAP 1 81 #define USE_DEFAULT_COLORMAP 1 80 #define USE_STANDARD_COLORMAP 0 82 #define USE_STANDARD_COLORMAP 0 81 83 82 XVisualInfo* G4OpenGLXViewer::vi_single_buffe 84 XVisualInfo* G4OpenGLXViewer::vi_single_buffer = 0; 83 XVisualInfo* G4OpenGLXViewer::vi_double_buffe 85 XVisualInfo* G4OpenGLXViewer::vi_double_buffer = 0; 84 86 85 extern "C" { 87 extern "C" { 86 static Bool G4OpenGLXViewerWaitForNotify (Di 88 static Bool G4OpenGLXViewerWaitForNotify (Display*, XEvent* e, char* arg) { 87 return (e->type == MapNotify) && (e->xmap. 89 return (e->type == MapNotify) && (e->xmap.window == (Window) arg); 88 } 90 } 89 } 91 } 90 92 91 void G4OpenGLXViewer::SetView () { 93 void G4OpenGLXViewer::SetView () { >> 94 #ifdef G4MULTITHREADED 92 if (G4Threading::IsMasterThread()) { 95 if (G4Threading::IsMasterThread()) { 93 glXMakeCurrent (dpy, win, cxMaster); 96 glXMakeCurrent (dpy, win, cxMaster); 94 } else { 97 } else { 95 glXMakeCurrent (dpy, win, cxVisSubThread); 98 glXMakeCurrent (dpy, win, cxVisSubThread); 96 } 99 } >> 100 #else >> 101 glXMakeCurrent (dpy, win, cxMaster); >> 102 #endif 97 G4OpenGLViewer::SetView (); 103 G4OpenGLViewer::SetView (); 98 } 104 } 99 105 100 void G4OpenGLXViewer::ShowView () { 106 void G4OpenGLXViewer::ShowView () { 101 // glXWaitGL (); //Wait for effects of all pr << 107 #ifdef G4MULTITHREADED >> 108 // G4int thread_id = G4Threading::G4GetThreadId(); >> 109 // G4cout << "G4OpenGLXViewer::ShowView: thread " << thread_id << G4endl; >> 110 #endif >> 111 glXWaitGL (); //Wait for effects of all previous OpenGL commands to 102 //be propagated before progres 112 //be propagated before progressing. 103 // JA: Commented out July 2021 - slows renderi << 104 // don't see any adverse effects. << 105 << 106 glFlush (); 113 glFlush (); 107 114 108 if (fVP.IsPicking()) { 115 if (fVP.IsPicking()) { 109 G4cout << 116 G4cout << 110 "Window activated for picking (left-mous 117 "Window activated for picking (left-mouse), exit (middle-mouse)." 111 << G4endl; 118 << G4endl; 112 while (true) { 119 while (true) { 113 if (XPending(dpy)) { 120 if (XPending(dpy)) { 114 XNextEvent(dpy, &event); 121 XNextEvent(dpy, &event); 115 if (event.type == ButtonPress && event.xbutt 122 if (event.type == ButtonPress && event.xbutton.button == 1) { 116 G4cout << Pick(event.xbutton.x, event.xbut 123 G4cout << Pick(event.xbutton.x, event.xbutton.y) << G4endl; 117 } 124 } 118 else if (event.type == ButtonPress && event. 125 else if (event.type == ButtonPress && event.xbutton.button == 2) break; 119 } 126 } 120 std::this_thread::sleep_for(std::chrono: 127 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 121 } 128 } 122 } 129 } 123 } 130 } 124 131 >> 132 #ifdef G4MULTITHREADED >> 133 125 void G4OpenGLXViewer::SwitchToVisSubThread() 134 void G4OpenGLXViewer::SwitchToVisSubThread() 126 { 135 { 127 #ifdef G4MULTITHREADED << 136 // G4cout << "G4OpenGLXViewer::SwitchToVisSubThread" << G4endl; 128 cxVisSubThread = glXCreateContext (dpy, vi, 137 cxVisSubThread = glXCreateContext (dpy, vi, cxMaster, true); 129 glXMakeCurrent (dpy, win, cxVisSubThread); 138 glXMakeCurrent (dpy, win, cxVisSubThread); 130 #endif << 131 } 139 } 132 140 133 void G4OpenGLXViewer::SwitchToMasterThread() 141 void G4OpenGLXViewer::SwitchToMasterThread() 134 { 142 { 135 #ifdef G4MULTITHREADED << 143 // G4cout << "G4OpenGLXViewer::SwitchToMasterThread" << G4endl; 136 glXMakeCurrent (dpy, win, cxMaster); 144 glXMakeCurrent (dpy, win, cxMaster); 137 // and destroy sub-thread context 145 // and destroy sub-thread context 138 glXDestroyContext (dpy, cxVisSubThread); 146 glXDestroyContext (dpy, cxVisSubThread); 139 #endif << 140 } 147 } 141 148 >> 149 #endif >> 150 142 void G4OpenGLXViewer::GetXConnection () { 151 void G4OpenGLXViewer::GetXConnection () { 143 // get a connection. 152 // get a connection. 144 dpy = XOpenDisplay (0); // Uses DISPLAY env 153 dpy = XOpenDisplay (0); // Uses DISPLAY environment variable. 145 if (!dpy) { 154 if (!dpy) { 146 fViewId = -1; // This flags an error. 155 fViewId = -1; // This flags an error. 147 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe 156 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewer couldn't open display." << G4endl; 148 return; 157 return; 149 } 158 } 150 159 151 // make sure OpenGL is supported and installed 160 // make sure OpenGL is supported and installed properly. 152 if (!glXQueryExtension (dpy, &errorBase, &ev 161 if (!glXQueryExtension (dpy, &errorBase, &eventBase)) { 153 fViewId = -1; // This flags an error. 162 fViewId = -1; // This flags an error. 154 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe 163 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewer X Server has no GLX extension." 155 << G4endl; 164 << G4endl; 156 return; 165 return; 157 } 166 } 158 167 159 } 168 } 160 169 161 void G4OpenGLXViewer::CreateGLXContext (XVisua 170 void G4OpenGLXViewer::CreateGLXContext (XVisualInfo* v) { 162 171 163 vi = v; 172 vi = v; 164 // get window's attributes 173 // get window's attributes 165 if (!XGetWindowAttributes(dpy, XRootWindow ( 174 if (!XGetWindowAttributes(dpy, XRootWindow (dpy, vi -> screen), &xwa)) { 166 fViewId = -1; // This flags an error. 175 fViewId = -1; // This flags an error. 167 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe 176 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewer couldn't return window attributes" 168 << G4endl; 177 << G4endl; 169 return; 178 return; 170 } 179 } 171 180 172 // create the master GLX context 181 // create the master GLX context 173 cxMaster = glXCreateContext (dpy, vi, 0, tru 182 cxMaster = glXCreateContext (dpy, vi, 0, true); 174 if (!cxMaster) { 183 if (!cxMaster) { 175 fViewId = -1; // This flags an error. 184 fViewId = -1; // This flags an error. 176 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe 185 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewer couldn't create context." 177 << G4endl; 186 << G4endl; 178 return; 187 return; 179 } 188 } 180 189 181 // New stab at getting a colormap 190 // New stab at getting a colormap 182 191 183 Status status; 192 Status status; 184 int i, numCmaps; 193 int i, numCmaps; 185 194 186 status = XmuLookupStandardColormap (dpy, 195 status = XmuLookupStandardColormap (dpy, 187 vi -> screen, 196 vi -> screen, 188 vi -> visualid, 197 vi -> visualid, 189 vi -> depth, 198 vi -> depth, 190 XA_RGB_BEST_MAP, 199 XA_RGB_BEST_MAP, 191 False, 200 False, 192 True); 201 True); 193 202 194 if (status == 1) { 203 if (status == 1) { 195 cmap = 0; 204 cmap = 0; 196 XStandardColormap* standardCmaps = XAllocS 205 XStandardColormap* standardCmaps = XAllocStandardColormap (); 197 status = XGetRGBColormaps (dpy, 206 status = XGetRGBColormaps (dpy, 198 XRootWindow (dpy, vi -> screen), 207 XRootWindow (dpy, vi -> screen), 199 &standardCmaps, 208 &standardCmaps, 200 &numCmaps, 209 &numCmaps, 201 XA_RGB_BEST_MAP); 210 XA_RGB_BEST_MAP); 202 if (status == 1) { 211 if (status == 1) { 203 for (i = 0; i < numCmaps; i++) { 212 for (i = 0; i < numCmaps; i++) { 204 if (standardCmaps[i].visualid == vi -> visua 213 if (standardCmaps[i].visualid == vi -> visualid) { 205 cmap = standardCmaps[i].colormap; 214 cmap = standardCmaps[i].colormap; 206 break; 215 break; 207 } 216 } 208 } 217 } 209 } 218 } 210 XFree (standardCmaps); 219 XFree (standardCmaps); 211 if(cmap) { 220 if(cmap) { 212 if (G4VisManager::GetVerbosity() >= G4Vi 221 if (G4VisManager::GetVerbosity() >= G4VisManager::confirmations) 213 G4cout << "Got standard cmap" << G4end 222 G4cout << "Got standard cmap" << G4endl; 214 } else { 223 } else { 215 //if (G4VisManager::GetVerbosity() >= G4 224 //if (G4VisManager::GetVerbosity() >= G4VisManager::errors) 216 // G4cerr << "G4OpenGLXViewer::G4OpenGL 225 // G4cerr << "G4OpenGLXViewer::G4OpenGLXViewer failed to allocate a standard colormap." 217 // << G4endl; 226 // << G4endl; 218 cmap = XCreateColormap (dpy, 227 cmap = XCreateColormap (dpy, 219 XRootWindow(dpy, 228 XRootWindow(dpy, vi -> screen), 220 vi -> visual, 229 vi -> visual, 221 AllocNone); 230 AllocNone); 222 if(cmap) { 231 if(cmap) { 223 if (G4VisManager::GetVerbosity() >= G4 232 if (G4VisManager::GetVerbosity() >= G4VisManager::confirmations) 224 G4cout << "Created own cmap" << G4en 233 G4cout << "Created own cmap" << G4endl; 225 } 234 } 226 //G.Barrand : at end, we should do a XFr 235 //G.Barrand : at end, we should do a XFreeColormap(dpy,cmap) when cmap is no more used. 227 } 236 } 228 } else { 237 } else { 229 cmap = XCreateColormap (dpy, 238 cmap = XCreateColormap (dpy, 230 XRootWindow(dpy, vi -> screen), 239 XRootWindow(dpy, vi -> screen), 231 vi -> visual, 240 vi -> visual, 232 AllocNone); 241 AllocNone); 233 if(cmap) { 242 if(cmap) { 234 if (G4VisManager::GetVerbosity() >= G4Vi 243 if (G4VisManager::GetVerbosity() >= G4VisManager::confirmations) 235 G4cout << "Created own cmap" << G4endl 244 G4cout << "Created own cmap" << G4endl; 236 } 245 } 237 //G.Barrand : at end, we should do a XFree 246 //G.Barrand : at end, we should do a XFreeColormap(dpy,cmap) when cmap is no more used. 238 } 247 } 239 248 240 if (!cmap) { 249 if (!cmap) { 241 fViewId = -1; // This flags an error. 250 fViewId = -1; // This flags an error. 242 if (G4VisManager::GetVerbosity() >= G4VisM 251 if (G4VisManager::GetVerbosity() >= G4VisManager::errors) 243 G4cout << "G4OpenGLXViewer::G4OpenGLXVie 252 G4cout << "G4OpenGLXViewer::G4OpenGLXViewer failed to allocate a Colormap." 244 << G4endl; 253 << G4endl; 245 return; 254 return; 246 } 255 } 247 256 248 } 257 } 249 258 250 void G4OpenGLXViewer::CreateMainWindow () { 259 void G4OpenGLXViewer::CreateMainWindow () { 251 260 252 // create a window 261 // create a window 253 swa.colormap = cmap; 262 swa.colormap = cmap; 254 swa.border_pixel = 0; 263 swa.border_pixel = 0; 255 swa.event_mask = ExposureMask | ButtonPressM 264 swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask; 256 swa.backing_store = WhenMapped; 265 swa.backing_store = WhenMapped; 257 266 258 // Window size and position... 267 // Window size and position... 259 size_hints = XAllocSizeHints(); 268 size_hints = XAllocSizeHints(); 260 269 261 ResizeWindow(fVP.GetWindowSizeHintX(),fVP.Ge 270 ResizeWindow(fVP.GetWindowSizeHintX(),fVP.GetWindowSizeHintY()); 262 271 263 G4int x_origin = fVP.GetWindowAbsoluteLocati 272 G4int x_origin = fVP.GetWindowAbsoluteLocationHintX(DisplayWidth(dpy, vi -> screen)); 264 273 265 // FIXME, screen size != window size on MAC 274 // FIXME, screen size != window size on MAC, but I don't know have to get the menuBar 266 // size on MAC. L.Garnier 01/2009 275 // size on MAC. L.Garnier 01/2009 267 G4int y_origin = fVP.GetWindowAbsoluteLocati 276 G4int y_origin = fVP.GetWindowAbsoluteLocationHintY(DisplayHeight(dpy, vi -> screen)); 268 277 269 size_hints->base_width = getWinWidth(); 278 size_hints->base_width = getWinWidth(); 270 size_hints->base_height = getWinHeight(); 279 size_hints->base_height = getWinHeight(); 271 size_hints->x = x_origin; 280 size_hints->x = x_origin; 272 size_hints->y = y_origin; 281 size_hints->y = y_origin; 273 if (fVP.IsWindowSizeHintX () && fVP.IsWindow 282 if (fVP.IsWindowSizeHintX () && fVP.IsWindowLocationHintX () && fVP.IsWindowLocationHintY ()) { 274 size_hints->flags |= PSize | PPosition; 283 size_hints->flags |= PSize | PPosition; 275 } else if (fVP.IsWindowSizeHintX () && !(fVP 284 } else if (fVP.IsWindowSizeHintX () && !(fVP.IsWindowLocationHintX () || fVP.IsWindowLocationHintY ())) { 276 size_hints->flags |= PSize; 285 size_hints->flags |= PSize; 277 } else if ((!fVP.IsWindowSizeHintX ()) && fV 286 } else if ((!fVP.IsWindowSizeHintX ()) && fVP.IsWindowLocationHintX () && fVP.IsWindowLocationHintY ()) { 278 size_hints->flags |= PPosition; 287 size_hints->flags |= PPosition; 279 } 288 } 280 if (G4VisManager::GetVerbosity() >= G4VisMan 289 if (G4VisManager::GetVerbosity() >= G4VisManager::confirmations) 281 G4cout << "Window name: " << fName << G4en 290 G4cout << "Window name: " << fName << G4endl; 282 strncpy (charViewName, fName, 99); charViewN 291 strncpy (charViewName, fName, 99); charViewName[99] = '\0'; 283 char *window_name = charViewName; 292 char *window_name = charViewName; 284 char *icon_name = charViewName; 293 char *icon_name = charViewName; 285 //char tmpatom[] = "XA_WM_NORMAL_HINTS"; 294 //char tmpatom[] = "XA_WM_NORMAL_HINTS"; 286 wm_hints = XAllocWMHints(); 295 wm_hints = XAllocWMHints(); 287 class_hints = XAllocClassHint(); 296 class_hints = XAllocClassHint(); 288 297 289 XStringListToTextProperty (&window_name, 1, 298 XStringListToTextProperty (&window_name, 1, &windowName); 290 XStringListToTextProperty (&icon_name, 1, &i 299 XStringListToTextProperty (&icon_name, 1, &iconName); 291 300 292 wm_hints -> initial_state = NormalState; 301 wm_hints -> initial_state = NormalState; 293 wm_hints -> input = True; 302 wm_hints -> input = True; 294 wm_hints -> icon_pixmap = icon_pixmap; 303 wm_hints -> icon_pixmap = icon_pixmap; 295 wm_hints -> flags = StateHint | IconPixmapHi 304 wm_hints -> flags = StateHint | IconPixmapHint | InputHint; 296 305 297 class_hints -> res_name = NewString("G4Open 306 class_hints -> res_name = NewString("G4OpenGL"); 298 class_hints -> res_class = NewString("G4Open 307 class_hints -> res_class = NewString("G4OpenGL"); 299 308 300 win = XCreateWindow (dpy, XRootWindow (dpy, 309 win = XCreateWindow (dpy, XRootWindow (dpy, vi -> screen), x_origin, 301 y_origin, getWinWidth( 310 y_origin, getWinWidth(), getWinHeight(), 0, vi -> depth, 302 InputOutput, vi -> vis 311 InputOutput, vi -> visual, 303 CWBorderPixel | CWColo 312 CWBorderPixel | CWColormap | 304 CWEventMask | CWBackin 313 CWEventMask | CWBackingStore, 305 &swa); 314 &swa); 306 315 307 XSetWMProperties (dpy, win, &windowName, &i 316 XSetWMProperties (dpy, win, &windowName, &iconName, 0, 0, 308 size_hints, wm_hints, cla 317 size_hints, wm_hints, class_hints); 309 318 310 // request X to Draw window on screen. 319 // request X to Draw window on screen. 311 XMapWindow (dpy, win); 320 XMapWindow (dpy, win); 312 321 313 // Wait for window to appear (wait for an "exp 322 // Wait for window to appear (wait for an "expose" event). 314 XIfEvent (dpy, &event, G4OpenGLXViewerWaitFo 323 XIfEvent (dpy, &event, G4OpenGLXViewerWaitForNotify, (char*) win); 315 324 316 // connect the context to a window 325 // connect the context to a window 317 Bool success = glXMakeCurrent (dpy, win, cxM 326 Bool success = glXMakeCurrent (dpy, win, cxMaster); 318 if (!success) { 327 if (!success) { 319 fViewId = -1; // This flags an error. 328 fViewId = -1; // This flags an error. 320 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe 329 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewer failed to attach a GLX context." 321 << G4endl; 330 << G4endl; 322 GLint error = GL_NO_ERROR; 331 GLint error = GL_NO_ERROR; 323 while ((error = glGetError()) != GL_NO_ERR 332 while ((error = glGetError()) != GL_NO_ERROR) { 324 switch (error) { 333 switch (error) { 325 case GL_INVALID_ENUM : 334 case GL_INVALID_ENUM : 326 G4cout << "GL Error: GL_INVALID_ENUM" << G4e 335 G4cout << "GL Error: GL_INVALID_ENUM" << G4endl;break; 327 case GL_INVALID_VALUE : 336 case GL_INVALID_VALUE : 328 G4cout << "GL Error: GL_INVALID_VALUE" << G4 337 G4cout << "GL Error: GL_INVALID_VALUE" << G4endl;break; 329 case GL_INVALID_OPERATION : 338 case GL_INVALID_OPERATION : 330 G4cout << "GL Error: GL_INVALID_OPERATION" < 339 G4cout << "GL Error: GL_INVALID_OPERATION" << G4endl;break; 331 case GL_OUT_OF_MEMORY : 340 case GL_OUT_OF_MEMORY : 332 G4cout << "GL Error: GL_OUT_OF_MEMORY" << G4 341 G4cout << "GL Error: GL_OUT_OF_MEMORY" << G4endl;break; 333 case GL_STACK_UNDERFLOW : 342 case GL_STACK_UNDERFLOW : 334 G4cout << "GL Error: GL_STACK_UNDERFLOW" << 343 G4cout << "GL Error: GL_STACK_UNDERFLOW" << G4endl;break; 335 case GL_STACK_OVERFLOW : 344 case GL_STACK_OVERFLOW : 336 G4cout << "GL Error: GL_STACK_OVERFLOW" << G 345 G4cout << "GL Error: GL_STACK_OVERFLOW" << G4endl;break; 337 default : 346 default : 338 G4cout << "GL Error: " << error << G4endl;br 347 G4cout << "GL Error: " << error << G4endl;break; 339 } 348 } 340 } 349 } 341 return; 350 return; 342 } 351 } 343 } 352 } 344 353 345 void G4OpenGLXViewer::CreateFontLists() 354 void G4OpenGLXViewer::CreateFontLists() 346 { 355 { 347 std::map<G4double,G4String> fonts; // G4VMa 356 std::map<G4double,G4String> fonts; // G4VMarker screen size and font name. 348 fonts[10.] = "-adobe-courier-bold-r-normal-- 357 fonts[10.] = "-adobe-courier-bold-r-normal--10-100-75-75-m-60-iso8859-1"; 349 fonts[11.] = "-adobe-courier-bold-r-normal-- 358 fonts[11.] = "-adobe-courier-bold-r-normal--11-80-100-100-m-60-iso8859-1"; 350 fonts[12.] = "-adobe-courier-bold-r-normal-- 359 fonts[12.] = "-adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1"; 351 fonts[13.] = "fixed"; 360 fonts[13.] = "fixed"; 352 fonts[14.] = "-adobe-courier-bold-r-normal-- 361 fonts[14.] = "-adobe-courier-bold-r-normal--14-100-100-100-m-90-iso8859-1"; 353 fonts[17.] = "-adobe-courier-bold-r-normal-- 362 fonts[17.] = "-adobe-courier-bold-r-normal--17-120-100-100-m-100-iso8859-1"; 354 fonts[18.] = "-adobe-courier-bold-r-normal-- 363 fonts[18.] = "-adobe-courier-bold-r-normal--18-180-75-75-m-110-iso8859-1"; 355 fonts[20.] = "-adobe-courier-bold-r-normal-- 364 fonts[20.] = "-adobe-courier-bold-r-normal--20-140-100-100-m-110-iso8859-1"; 356 fonts[24.] = "-adobe-courier-bold-r-normal-- 365 fonts[24.] = "-adobe-courier-bold-r-normal--24-240-75-75-m-150-iso8859-1"; 357 fonts[25.] = "-adobe-courier-bold-r-normal-- 366 fonts[25.] = "-adobe-courier-bold-r-normal--25-180-100-100-m-150-iso8859-1"; 358 fonts[34.] = "-adobe-courier-bold-r-normal-- 367 fonts[34.] = "-adobe-courier-bold-r-normal--34-240-100-100-m-200-iso8859-1"; 359 std::map<G4double,G4String>::const_iterator 368 std::map<G4double,G4String>::const_iterator i; 360 for (i = fonts.begin(); i != fonts.end(); ++ 369 for (i = fonts.begin(); i != fonts.end(); ++i) { 361 XFontStruct* font_info = XLoadQueryFont(dp 370 XFontStruct* font_info = XLoadQueryFont(dpy, i->second); 362 if (!font_info) { 371 if (!font_info) { 363 G4cerr << 372 G4cerr << 364 "G4OpenGLXViewer::CreateFontLists XLoadQuery 373 "G4OpenGLXViewer::CreateFontLists XLoadQueryFont failed for font\n " 365 << i->second 374 << i->second 366 << G4endl; 375 << G4endl; 367 continue; 376 continue; 368 } 377 } 369 G4int font_base = glGenLists(256); 378 G4int font_base = glGenLists(256); 370 if (!font_base) { 379 if (!font_base) { 371 G4cerr << 380 G4cerr << 372 "G4OpenGLXViewer::CreateFontLists out of dis 381 "G4OpenGLXViewer::CreateFontLists out of display lists for fonts." 373 << G4endl; 382 << G4endl; 374 continue; 383 continue; 375 } 384 } 376 G4int first = font_info->min_char_or_byte2 385 G4int first = font_info->min_char_or_byte2; 377 G4int last = font_info->max_char_or_byte2 386 G4int last = font_info->max_char_or_byte2; 378 glXUseXFont(font_info->fid, first, last-fi 387 glXUseXFont(font_info->fid, first, last-first+1, font_base + first); 379 G4int width = font_info->max_bounds.width; 388 G4int width = font_info->max_bounds.width; 380 G4OpenGLFontBaseStore::AddFontBase 389 G4OpenGLFontBaseStore::AddFontBase 381 (this, font_base, i->first, i->second, w 390 (this, font_base, i->first, i->second, width); 382 } 391 } 383 } 392 } 384 393 385 void G4OpenGLXViewer::DrawText(const G4Text& g 394 void G4OpenGLXViewer::DrawText(const G4Text& g4text) 386 { 395 { 387 if (isGl2psWriting()) { 396 if (isGl2psWriting()) { 388 397 389 G4OpenGLViewer::DrawText(g4text); 398 G4OpenGLViewer::DrawText(g4text); 390 399 391 } else { 400 } else { 392 401 393 G4VSceneHandler::MarkerSizeType sizeType; 402 G4VSceneHandler::MarkerSizeType sizeType; 394 G4double size = fSceneHandler.GetMarkerSiz 403 G4double size = fSceneHandler.GetMarkerSize(g4text,sizeType); 395 404 396 const G4OpenGLFontBaseStore::FontInfo& fon 405 const G4OpenGLFontBaseStore::FontInfo& fontInfo = 397 G4OpenGLFontBaseStore::GetFontInfo(this, 406 G4OpenGLFontBaseStore::GetFontInfo(this,(int)size); 398 if (fontInfo.fFontBase < 0) { 407 if (fontInfo.fFontBase < 0) { 399 static G4int callCount = 0; 408 static G4int callCount = 0; 400 ++callCount; 409 ++callCount; 401 //if (callCount <= 10 || callCount%100 = 410 //if (callCount <= 10 || callCount%100 == 0) { 402 if (callCount <= 1) { 411 if (callCount <= 1) { 403 G4cout << 412 G4cout << 404 "G4OpenGLXViewer::DrawText: No fonts avail 413 "G4OpenGLXViewer::DrawText: No fonts available for \"" 405 << fName << 414 << fName << 406 "\"\n Called with " 415 "\"\n Called with " 407 << g4text 416 << g4text 408 << G4endl; 417 << G4endl; 409 } 418 } 410 return; 419 return; 411 } 420 } 412 421 413 const G4Colour& c = fSceneHandler.GetTextC 422 const G4Colour& c = fSceneHandler.GetTextColour(g4text); 414 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlu 423 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlue(),c.GetAlpha()); 415 424 416 G4Point3D position = g4text.GetPosition(); 425 G4Point3D position = g4text.GetPosition(); 417 426 418 G4String textString = g4text.GetText(); 427 G4String textString = g4text.GetText(); 419 const char* textCString = textString.c_str 428 const char* textCString = textString.c_str(); 420 429 421 // Set position for raster-style drawers ( 430 // Set position for raster-style drawers (X, Xm) 422 glRasterPos3d(position.x(),position.y(),po 431 glRasterPos3d(position.x(),position.y(),position.z()); 423 432 424 glPushAttrib(GL_LIST_BIT); 433 glPushAttrib(GL_LIST_BIT); 425 434 426 // Calculate move for centre and right adj 435 // Calculate move for centre and right adjustment 427 G4double span = textString.size() * fontIn 436 G4double span = textString.size() * fontInfo.fWidth; 428 G4double xmove = 0., ymove = 0.; 437 G4double xmove = 0., ymove = 0.; 429 switch (g4text.GetLayout()) { 438 switch (g4text.GetLayout()) { 430 case G4Text::left: break; 439 case G4Text::left: break; 431 case G4Text::centre: xmove -= span / 2.; b 440 case G4Text::centre: xmove -= span / 2.; break; 432 case G4Text::right: xmove -= span; 441 case G4Text::right: xmove -= span; 433 } 442 } 434 443 435 //Add offsets 444 //Add offsets 436 xmove += g4text.GetXOffset(); 445 xmove += g4text.GetXOffset(); 437 ymove += g4text.GetYOffset(); 446 ymove += g4text.GetYOffset(); 438 447 439 // Do move 448 // Do move 440 glBitmap(0,0,0,0,xmove,ymove,0); 449 glBitmap(0,0,0,0,xmove,ymove,0); 441 450 442 // Write characters 451 // Write characters 443 glListBase(fontInfo.fFontBase); 452 glListBase(fontInfo.fFontBase); 444 glCallLists((G4int)strlen(textCString),GL_ << 453 glCallLists(strlen(textCString),GL_UNSIGNED_BYTE,(GLubyte*)textCString); 445 glPopAttrib(); 454 glPopAttrib(); 446 } 455 } 447 } 456 } 448 457 449 458 450 G4OpenGLXViewer::G4OpenGLXViewer (G4OpenGLScen 459 G4OpenGLXViewer::G4OpenGLXViewer (G4OpenGLSceneHandler& scene): 451 G4VViewer (scene, -1), 460 G4VViewer (scene, -1), 452 G4OpenGLViewer (scene), 461 G4OpenGLViewer (scene), 453 vi_immediate (0), 462 vi_immediate (0), 454 vi_stored (0), 463 vi_stored (0), 455 vi (0), 464 vi (0), 456 cmap (0) 465 cmap (0) 457 { 466 { 458 // To satisfy Coverity 467 // To satisfy Coverity 459 xwa.visual = 0; 468 xwa.visual = 0; 460 iconName.value = 0; 469 iconName.value = 0; 461 xwa.screen = 0; 470 xwa.screen = 0; 462 windowName.value = 0; 471 windowName.value = 0; 463 472 464 GetXConnection (); 473 GetXConnection (); 465 if (fViewId < 0) return; 474 if (fViewId < 0) return; 466 475 467 // Try for a visual suitable for OpenGLImmed 476 // Try for a visual suitable for OpenGLImmediate.. 468 // first try for a single buffered RGB windo 477 // first try for a single buffered RGB window 469 if (!vi_single_buffer) { 478 if (!vi_single_buffer) { 470 vi_single_buffer = 479 vi_single_buffer = 471 glXChooseVisual (dpy, XDefaultScreen (dp 480 glXChooseVisual (dpy, XDefaultScreen (dpy), snglBuf_RGBA); 472 //G.Barrand : we should do a XFree(vi_sing 481 //G.Barrand : we should do a XFree(vi_single_buffer) at end; 473 } 482 } 474 if (!vi_double_buffer) { 483 if (!vi_double_buffer) { 475 vi_double_buffer = 484 vi_double_buffer = 476 glXChooseVisual (dpy, XDefaultScreen (dp 485 glXChooseVisual (dpy, XDefaultScreen (dpy), dblBuf_RGBA); 477 //G.Barrand : we should do a XFree(vi_doub 486 //G.Barrand : we should do a XFree(vi_double_buffer) at end; 478 } 487 } 479 488 480 if (vi_single_buffer || vi_double_buffer) { 489 if (vi_single_buffer || vi_double_buffer) { 481 if (!vi_double_buffer) { 490 if (!vi_double_buffer) { 482 G4cout << 491 G4cout << 483 "G4OpenGLXViewer::G4OpenGLXViewer: unable to 492 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get a double buffer visual." 484 "\n Working with a single buffer." 493 "\n Working with a single buffer." 485 << G4endl; 494 << G4endl; 486 } 495 } 487 } else { 496 } else { 488 if (!vi_single_buffer) { 497 if (!vi_single_buffer) { 489 G4cout << 498 G4cout << 490 "G4OpenGLXViewer::G4OpenGLXViewer: unable to 499 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get a single buffer visual." 491 << G4endl; 500 << G4endl; 492 } 501 } 493 if (!vi_double_buffer) { 502 if (!vi_double_buffer) { 494 G4cout << 503 G4cout << 495 "G4OpenGLXViewer::G4OpenGLXViewer: unable to 504 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get a double buffer visual." 496 << G4endl; 505 << G4endl; 497 } 506 } 498 } 507 } 499 508 500 if (vi_single_buffer) { 509 if (vi_single_buffer) { 501 vi_immediate = vi_single_buffer; 510 vi_immediate = vi_single_buffer; 502 attributeList = snglBuf_RGBA; 511 attributeList = snglBuf_RGBA; 503 } 512 } 504 513 505 if (!vi_immediate){ 514 if (!vi_immediate){ 506 // next try for a double buffered RGB, but 515 // next try for a double buffered RGB, but Draw to top buffer 507 if (vi_double_buffer) { 516 if (vi_double_buffer) { 508 vi_immediate = vi_double_buffer; 517 vi_immediate = vi_double_buffer; 509 attributeList = dblBuf_RGBA; 518 attributeList = dblBuf_RGBA; 510 } 519 } 511 } 520 } 512 521 513 // Now try for a visual suitable for OpenGLS 522 // Now try for a visual suitable for OpenGLStored... 514 // Try for a double buffered RGB window 523 // Try for a double buffered RGB window 515 if (vi_double_buffer) { 524 if (vi_double_buffer) { 516 vi_stored = vi_double_buffer; 525 vi_stored = vi_double_buffer; 517 attributeList = dblBuf_RGBA; 526 attributeList = dblBuf_RGBA; 518 } 527 } 519 528 520 if (!vi_immediate || !vi_stored) { 529 if (!vi_immediate || !vi_stored) { 521 G4cout << 530 G4cout << 522 "G4OpenGLXViewer::G4OpenGLXViewer: unable 531 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get required visuals." 523 << G4endl; 532 << G4endl; 524 fViewId = -1; // This flags an error. 533 fViewId = -1; // This flags an error. 525 } 534 } 526 535 527 // glClearColor (0., 0., 0., 0.); 536 // glClearColor (0., 0., 0., 0.); 528 // glClearDepth (1.); 537 // glClearDepth (1.); 529 } 538 } 530 539 531 G4OpenGLXViewer::~G4OpenGLXViewer () { 540 G4OpenGLXViewer::~G4OpenGLXViewer () { 532 if (fViewId >= 0) { 541 if (fViewId >= 0) { 533 //Close a window from here 542 //Close a window from here 534 glXMakeCurrent (dpy, None, NULL); 543 glXMakeCurrent (dpy, None, NULL); 535 glXDestroyContext (dpy, cxMaster); 544 glXDestroyContext (dpy, cxMaster); 536 if (win) XDestroyWindow (dpy, win); // ... 545 if (win) XDestroyWindow (dpy, win); // ...if already deleted in 537 // sub-class G4OpenGLXmViewer. 546 // sub-class G4OpenGLXmViewer. 538 // We should do a XFreeColormap(dpy,cmap); 547 // We should do a XFreeColormap(dpy,cmap); if cmap had been get with XCreateColormap. 539 XFlush (dpy); 548 XFlush (dpy); 540 } 549 } 541 } 550 } 542 551 >> 552 >> 553 #endif 543 554