Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // 23 // >> 24 // $Id: G4OpenGLXViewer.cc,v 1.23 2004/12/07 23:40:59 perl Exp $ >> 25 // GEANT4 tag $Name: geant4-07-00-cand-03 $ 27 // 26 // 28 // 27 // 29 // Andrew Walkden 7th February 1997 28 // Andrew Walkden 7th February 1997 30 // G4OpenGLXViewer : Class to provide XWindows 29 // G4OpenGLXViewer : Class to provide XWindows specific 31 // functionality for OpenGL in 30 // functionality for OpenGL in GEANT4 32 31 >> 32 #ifdef G4VIS_BUILD_OPENGLX_DRIVER >> 33 33 #include "G4OpenGLXViewer.hh" 34 #include "G4OpenGLXViewer.hh" 34 35 35 #include "G4OpenGLSceneHandler.hh" << 36 #include "G4ios.hh" 36 #include "G4OpenGLFontBaseStore.hh" << 37 37 38 #include "G4VisExtent.hh" 38 #include "G4VisExtent.hh" 39 #include "G4LogicalVolume.hh" 39 #include "G4LogicalVolume.hh" 40 #include "G4VSolid.hh" 40 #include "G4VSolid.hh" 41 #include "G4Point3D.hh" 41 #include "G4Point3D.hh" 42 #include "G4Normal3D.hh" 42 #include "G4Normal3D.hh" 43 #include "G4StateManager.hh" << 44 #include "G4VisManager.hh" << 45 #include "G4Text.hh" << 46 #include "G4Threading.hh" << 47 43 48 #include <X11/Xatom.h> 44 #include <X11/Xatom.h> 49 #include <X11/Xutil.h> 45 #include <X11/Xutil.h> 50 #include <X11/Xmu/StdCmap.h> << 51 46 52 #include <assert.h> 47 #include <assert.h> 53 #include <sstream> << 54 #include <chrono> << 55 #include <thread> << 56 48 57 int G4OpenGLXViewer::snglBuf_RGBA[12] = 49 int G4OpenGLXViewer::snglBuf_RGBA[12] = 58 { GLX_RGBA, 50 { GLX_RGBA, 59 GLX_RED_SIZE, 1, 51 GLX_RED_SIZE, 1, 60 GLX_GREEN_SIZE, 1, 52 GLX_GREEN_SIZE, 1, 61 GLX_BLUE_SIZE, 1, 53 GLX_BLUE_SIZE, 1, 62 GLX_DEPTH_SIZE, 1, 54 GLX_DEPTH_SIZE, 1, 63 GLX_STENCIL_SIZE, 1, 55 GLX_STENCIL_SIZE, 1, 64 None }; 56 None }; 65 57 66 int G4OpenGLXViewer::dblBuf_RGBA[13] = 58 int G4OpenGLXViewer::dblBuf_RGBA[13] = 67 { GLX_RGBA, 59 { GLX_RGBA, 68 GLX_RED_SIZE, 1, 60 GLX_RED_SIZE, 1, 69 GLX_GREEN_SIZE, 1, 61 GLX_GREEN_SIZE, 1, 70 GLX_BLUE_SIZE, 1, 62 GLX_BLUE_SIZE, 1, 71 GLX_DOUBLEBUFFER, 63 GLX_DOUBLEBUFFER, 72 GLX_DEPTH_SIZE, 1, 64 GLX_DEPTH_SIZE, 1, 73 GLX_STENCIL_SIZE, 1, 65 GLX_STENCIL_SIZE, 1, 74 None }; 66 None }; 75 67 76 #define NewString(str) \ 68 #define NewString(str) \ 77 ((str) != 0 ? (strncpy((char*)malloc((unsign << 69 ((str) != NULL ? (strcpy((char*)malloc((unsigned)strlen(str) + 1), str)) : (char*)NULL) 78 70 79 #define USE_DEFAULT_COLORMAP 1 71 #define USE_DEFAULT_COLORMAP 1 80 #define USE_STANDARD_COLORMAP 0 72 #define USE_STANDARD_COLORMAP 0 81 73 >> 74 static const char* gouraudtriangleEPS[] = >> 75 { >> 76 "/bd{bind def}bind def /triangle { aload pop setrgbcolor aload pop 5 3", >> 77 "roll 4 2 roll 3 2 roll exch moveto lineto lineto closepath fill } bd", >> 78 "/computediff1 { 2 copy sub abs threshold ge {pop pop pop true} { exch 2", >> 79 "index sub abs threshold ge { pop pop true} { sub abs threshold ge } ifelse", >> 80 "} ifelse } bd /computediff3 { 3 copy 0 get 3 1 roll 0 get 3 1 roll 0 get", >> 81 "computediff1 {true} { 3 copy 1 get 3 1 roll 1 get 3 1 roll 1 get", >> 82 "computediff1 {true} { 3 copy 2 get 3 1 roll 2 get 3 1 roll 2 get", >> 83 "computediff1 } ifelse } ifelse } bd /middlecolor { aload pop 4 -1 roll", >> 84 "aload pop 4 -1 roll add 2 div 5 1 roll 3 -1 roll add 2 div 3 1 roll add 2", >> 85 "div 3 1 roll exch 3 array astore } bd /gouraudtriangle { computediff3 { 4", >> 86 "-1 roll aload 7 1 roll 6 -1 roll pop 3 -1 roll pop add 2 div 3 1 roll add", >> 87 "2 div exch 3 -1 roll aload 7 1 roll exch pop 4 -1 roll pop add 2 div 3 1", >> 88 "roll add 2 div exch 3 -1 roll aload 7 1 roll pop 3 -1 roll pop add 2 div 3", >> 89 "1 roll add 2 div exch 7 3 roll 10 -3 roll dup 3 index middlecolor 4 1 roll", >> 90 "2 copy middlecolor 4 1 roll 3 copy pop middlecolor 4 1 roll 13 -1 roll", >> 91 "aload pop 17 index 6 index 15 index 19 index 6 index 17 index 6 array", >> 92 "astore 10 index 10 index 14 index gouraudtriangle 17 index 5 index 17", >> 93 "index 19 index 5 index 19 index 6 array astore 10 index 9 index 13 index", >> 94 "gouraudtriangle 13 index 16 index 5 index 15 index 18 index 5 index 6", >> 95 "array astore 12 index 12 index 9 index gouraudtriangle 17 index 16 index", >> 96 "15 index 19 index 18 index 17 index 6 array astore 10 index 12 index 14", >> 97 "index gouraudtriangle 18 {pop} repeat } { aload pop 5 3 roll aload pop 7 3", >> 98 "roll aload pop 9 3 roll 4 index 6 index 4 index add add 3 div 10 1 roll 7", >> 99 "index 5 index 3 index add add 3 div 10 1 roll 6 index 4 index 2 index add", >> 100 "add 3 div 10 1 roll 9 {pop} repeat 3 array astore triangle } ifelse } bd", >> 101 NULL >> 102 }; >> 103 82 XVisualInfo* G4OpenGLXViewer::vi_single_buffe 104 XVisualInfo* G4OpenGLXViewer::vi_single_buffer = 0; 83 XVisualInfo* G4OpenGLXViewer::vi_double_buffe 105 XVisualInfo* G4OpenGLXViewer::vi_double_buffer = 0; 84 106 85 extern "C" { 107 extern "C" { 86 static Bool G4OpenGLXViewerWaitForNotify (Di << 108 Bool G4OpenGLXViewerWaitForNotify (Display*, XEvent* e, char* arg) { 87 return (e->type == MapNotify) && (e->xmap. 109 return (e->type == MapNotify) && (e->xmap.window == (Window) arg); 88 } 110 } 89 } 111 } 90 112 91 void G4OpenGLXViewer::SetView () { 113 void G4OpenGLXViewer::SetView () { 92 if (G4Threading::IsMasterThread()) { << 114 glXMakeCurrent (dpy, win, cx); 93 glXMakeCurrent (dpy, win, cxMaster); << 115 G4OpenGLViewer::SetView (); 94 } else { << 95 glXMakeCurrent (dpy, win, cxVisSubThread); << 96 } << 97 G4OpenGLViewer::SetView (); << 98 } 116 } 99 117 100 void G4OpenGLXViewer::ShowView () { 118 void G4OpenGLXViewer::ShowView () { 101 // glXWaitGL (); //Wait for effects of all pr << 119 glXWaitGL (); //Wait for effects of all previous OpenGL commands to 102 //be propagated before progres << 120 //be propogated before progressing. 103 // JA: Commented out July 2021 - slows renderi << 104 // don't see any adverse effects. << 105 << 106 glFlush (); 121 glFlush (); 107 << 108 if (fVP.IsPicking()) { << 109 G4cout << << 110 "Window activated for picking (left-mous << 111 << G4endl; << 112 while (true) { << 113 if (XPending(dpy)) { << 114 XNextEvent(dpy, &event); << 115 if (event.type == ButtonPress && event.xbutt << 116 G4cout << Pick(event.xbutton.x, event.xbut << 117 } << 118 else if (event.type == ButtonPress && event. << 119 } << 120 std::this_thread::sleep_for(std::chrono: << 121 } << 122 } << 123 } 122 } 124 123 125 void G4OpenGLXViewer::SwitchToVisSubThread() << 124 void G4OpenGLXViewer::FinishView () { 126 { << 125 glXWaitGL (); //Wait for effects of all previous OpenGL commands to 127 #ifdef G4MULTITHREADED << 126 //be propogated before progressing. 128 cxVisSubThread = glXCreateContext (dpy, vi, << 127 if (doublebuffer == true) { 129 glXMakeCurrent (dpy, win, cxVisSubThread); << 128 glXSwapBuffers (dpy, win); 130 #endif << 129 } 131 } << 130 else glFlush (); 132 << 133 void G4OpenGLXViewer::SwitchToMasterThread() << 134 { << 135 #ifdef G4MULTITHREADED << 136 glXMakeCurrent (dpy, win, cxMaster); << 137 // and destroy sub-thread context << 138 glXDestroyContext (dpy, cxVisSubThread); << 139 #endif << 140 } 131 } 141 132 142 void G4OpenGLXViewer::GetXConnection () { 133 void G4OpenGLXViewer::GetXConnection () { 143 // get a connection. 134 // get a connection. 144 dpy = XOpenDisplay (0); // Uses DISPLAY env << 135 dpy = XOpenDisplay (0); 145 if (!dpy) { 136 if (!dpy) { 146 fViewId = -1; // This flags an error. 137 fViewId = -1; // This flags an error. 147 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe << 138 G4cerr << "G4OpenGLViewer::G4OpenGLViewer couldn't open display." << G4endl; 148 return; 139 return; 149 } 140 } 150 141 151 // make sure OpenGL is supported and installed 142 // make sure OpenGL is supported and installed properly. 152 if (!glXQueryExtension (dpy, &errorBase, &ev 143 if (!glXQueryExtension (dpy, &errorBase, &eventBase)) { 153 fViewId = -1; // This flags an error. 144 fViewId = -1; // This flags an error. 154 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe << 145 G4cerr << "G4OpenGLViewer::G4OpenGLViewer X Server has no GLX extension." 155 << G4endl; 146 << G4endl; 156 return; 147 return; 157 } 148 } 158 << 159 } 149 } 160 150 161 void G4OpenGLXViewer::CreateGLXContext (XVisua 151 void G4OpenGLXViewer::CreateGLXContext (XVisualInfo* v) { 162 152 163 vi = v; 153 vi = v; 164 // get window's attributes 154 // get window's attributes 165 if (!XGetWindowAttributes(dpy, XRootWindow ( 155 if (!XGetWindowAttributes(dpy, XRootWindow (dpy, vi -> screen), &xwa)) { 166 fViewId = -1; // This flags an error. 156 fViewId = -1; // This flags an error. 167 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe << 157 G4cerr << "G4OpenGLViewer::G4OpenGLViewer couldn't return window attributes" 168 << G4endl; 158 << G4endl; 169 return; 159 return; 170 } 160 } 171 161 172 // create the master GLX context << 162 // create a GLX context 173 cxMaster = glXCreateContext (dpy, vi, 0, tru << 163 cx = glXCreateContext (dpy, vi, 0, true); 174 if (!cxMaster) { << 164 if (!cx) { 175 fViewId = -1; // This flags an error. 165 fViewId = -1; // This flags an error. 176 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe << 166 G4cerr << "G4OpenGLViewer::G4OpenGLViewer couldn't create context." 177 << G4endl; 167 << G4endl; 178 return; 168 return; 179 } 169 } 180 170 181 // New stab at getting a colormap 171 // New stab at getting a colormap 182 172 183 Status status; 173 Status status; >> 174 XStandardColormap *standardCmaps = XAllocStandardColormap (); 184 int i, numCmaps; 175 int i, numCmaps; 185 176 186 status = XmuLookupStandardColormap (dpy, 177 status = XmuLookupStandardColormap (dpy, 187 vi -> screen, 178 vi -> screen, 188 vi -> visualid, 179 vi -> visualid, 189 vi -> depth, 180 vi -> depth, 190 XA_RGB_BEST_MAP, << 181 XA_RGB_DEFAULT_MAP, 191 False, 182 False, 192 True); 183 True); 193 << 184 194 if (status == 1) { 185 if (status == 1) { 195 cmap = 0; << 196 XStandardColormap* standardCmaps = XAllocS << 197 status = XGetRGBColormaps (dpy, 186 status = XGetRGBColormaps (dpy, 198 XRootWindow (dpy, vi -> screen), << 187 XRootWindow (dpy, vi -> screen), 199 &standardCmaps, 188 &standardCmaps, 200 &numCmaps, 189 &numCmaps, 201 XA_RGB_BEST_MAP); << 190 XA_RGB_DEFAULT_MAP); 202 if (status == 1) { << 191 if (status == 1) 203 for (i = 0; i < numCmaps; i++) { << 192 for (i = 0; i < numCmaps; i++) 204 if (standardCmaps[i].visualid == vi -> visua 193 if (standardCmaps[i].visualid == vi -> visualid) { 205 cmap = standardCmaps[i].colormap; 194 cmap = standardCmaps[i].colormap; 206 break; << 195 XFree (standardCmaps); 207 } 196 } 208 } << 197 G4cout << "Got standard cmap" << G4endl; 209 } << 210 XFree (standardCmaps); << 211 if(cmap) { << 212 if (G4VisManager::GetVerbosity() >= G4Vi << 213 G4cout << "Got standard cmap" << G4end << 214 } else { << 215 //if (G4VisManager::GetVerbosity() >= G4 << 216 // G4cerr << "G4OpenGLXViewer::G4OpenGL << 217 // << G4endl; << 218 cmap = XCreateColormap (dpy, << 219 XRootWindow(dpy, << 220 vi -> visual, << 221 AllocNone); << 222 if(cmap) { << 223 if (G4VisManager::GetVerbosity() >= G4 << 224 G4cout << "Created own cmap" << G4en << 225 } << 226 //G.Barrand : at end, we should do a XFr << 227 } << 228 } else { 198 } else { 229 cmap = XCreateColormap (dpy, 199 cmap = XCreateColormap (dpy, 230 XRootWindow(dpy, vi -> screen), 200 XRootWindow(dpy, vi -> screen), 231 vi -> visual, 201 vi -> visual, 232 AllocNone); 202 AllocNone); 233 if(cmap) { << 203 G4cout << "Created own cmap" << G4endl; 234 if (G4VisManager::GetVerbosity() >= G4Vi << 235 G4cout << "Created own cmap" << G4endl << 236 } << 237 //G.Barrand : at end, we should do a XFree << 238 } 204 } 239 205 240 if (!cmap) { 206 if (!cmap) { 241 fViewId = -1; // This flags an error. 207 fViewId = -1; // This flags an error. 242 if (G4VisManager::GetVerbosity() >= G4VisM << 208 G4cerr << "G4OpenGLViewer::G4OpenGLViewer failed to allocate a Colormap." 243 G4cout << "G4OpenGLXViewer::G4OpenGLXVie << 209 << G4endl; 244 << G4endl; << 245 return; 210 return; 246 } 211 } 247 212 248 } 213 } 249 214 250 void G4OpenGLXViewer::CreateMainWindow () { 215 void G4OpenGLXViewer::CreateMainWindow () { 251 216 252 // create a window 217 // create a window 253 swa.colormap = cmap; 218 swa.colormap = cmap; 254 swa.border_pixel = 0; 219 swa.border_pixel = 0; 255 swa.event_mask = ExposureMask | ButtonPressM 220 swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask; 256 swa.backing_store = WhenMapped; 221 swa.backing_store = WhenMapped; 257 222 258 // Window size and position... << 223 // G4int WinSize_x; 259 size_hints = XAllocSizeHints(); << 224 // G4int WinSize_y; 260 << 225 if (xwa.width > xwa.height) { 261 ResizeWindow(fVP.GetWindowSizeHintX(),fVP.Ge << 226 WinSize_x = (xwa.height)/2; 262 << 227 WinSize_y = (xwa.height)/2; 263 G4int x_origin = fVP.GetWindowAbsoluteLocati << 228 } 264 << 229 else { 265 // FIXME, screen size != window size on MAC << 230 WinSize_x = (xwa.width)/2; 266 // size on MAC. L.Garnier 01/2009 << 231 WinSize_y = (xwa.width)/2; 267 G4int y_origin = fVP.GetWindowAbsoluteLocati << 232 } 268 << 233 if (WinSize_x < fVP.GetWindowSizeHintX ()) 269 size_hints->base_width = getWinWidth(); << 234 WinSize_x = fVP.GetWindowSizeHintX (); 270 size_hints->base_height = getWinHeight(); << 235 if (WinSize_y < fVP.GetWindowSizeHintY ()) 271 size_hints->x = x_origin; << 236 WinSize_y = fVP.GetWindowSizeHintY (); 272 size_hints->y = y_origin; << 237 x_origin = xwa.x; 273 if (fVP.IsWindowSizeHintX () && fVP.IsWindow << 238 y_origin = xwa.y; 274 size_hints->flags |= PSize | PPosition; << 239 G4cout << "Window name: " << fName << G4endl; 275 } else if (fVP.IsWindowSizeHintX () && !(fVP << 240 strncpy (charViewName, fName, 100); 276 size_hints->flags |= PSize; << 277 } else if ((!fVP.IsWindowSizeHintX ()) && fV << 278 size_hints->flags |= PPosition; << 279 } << 280 if (G4VisManager::GetVerbosity() >= G4VisMan << 281 G4cout << "Window name: " << fName << G4en << 282 strncpy (charViewName, fName, 99); charViewN << 283 char *window_name = charViewName; 241 char *window_name = charViewName; 284 char *icon_name = charViewName; 242 char *icon_name = charViewName; 285 //char tmpatom[] = "XA_WM_NORMAL_HINTS"; 243 //char tmpatom[] = "XA_WM_NORMAL_HINTS"; >> 244 size_hints = XAllocSizeHints(); 286 wm_hints = XAllocWMHints(); 245 wm_hints = XAllocWMHints(); 287 class_hints = XAllocClassHint(); 246 class_hints = XAllocClassHint(); 288 247 >> 248 size_hints -> flags = PPosition | PSize | PMinSize; >> 249 size_hints -> min_width = 300; >> 250 size_hints -> min_height = 200; >> 251 289 XStringListToTextProperty (&window_name, 1, 252 XStringListToTextProperty (&window_name, 1, &windowName); 290 XStringListToTextProperty (&icon_name, 1, &i 253 XStringListToTextProperty (&icon_name, 1, &iconName); 291 254 292 wm_hints -> initial_state = NormalState; 255 wm_hints -> initial_state = NormalState; 293 wm_hints -> input = True; 256 wm_hints -> input = True; 294 wm_hints -> icon_pixmap = icon_pixmap; 257 wm_hints -> icon_pixmap = icon_pixmap; 295 wm_hints -> flags = StateHint | IconPixmapHi 258 wm_hints -> flags = StateHint | IconPixmapHint | InputHint; 296 259 297 class_hints -> res_name = NewString("G4Open 260 class_hints -> res_name = NewString("G4OpenGL"); 298 class_hints -> res_class = NewString("G4Open 261 class_hints -> res_class = NewString("G4OpenGL"); 299 262 300 win = XCreateWindow (dpy, XRootWindow (dpy, << 263 win = XCreateWindow (dpy, XRootWindow (dpy, vi -> screen), x_origin, 301 y_origin, getWinWidth( << 264 y_origin, WinSize_x, WinSize_y, 0, vi -> depth, 302 InputOutput, vi -> vis << 265 InputOutput, vi -> visual, 303 CWBorderPixel | CWColo << 266 CWBorderPixel | CWColormap | 304 CWEventMask | CWBackin << 267 CWEventMask | CWBackingStore, 305 &swa); << 268 &swa); 306 269 307 XSetWMProperties (dpy, win, &windowName, &i << 270 XSetWMProperties (dpy, win, &windowName, &iconName, 0, 0, 308 size_hints, wm_hints, cla << 271 size_hints, wm_hints, class_hints); 309 272 310 // request X to Draw window on screen. 273 // request X to Draw window on screen. 311 XMapWindow (dpy, win); 274 XMapWindow (dpy, win); 312 275 313 // Wait for window to appear (wait for an "exp 276 // Wait for window to appear (wait for an "expose" event). 314 XIfEvent (dpy, &event, G4OpenGLXViewerWaitFo 277 XIfEvent (dpy, &event, G4OpenGLXViewerWaitForNotify, (char*) win); 315 278 316 // connect the context to a window 279 // connect the context to a window 317 Bool success = glXMakeCurrent (dpy, win, cxM << 280 glXMakeCurrent (dpy, win, cx); 318 if (!success) { << 319 fViewId = -1; // This flags an error. << 320 G4cerr << "G4OpenGLXViewer::G4OpenGLXViewe << 321 << G4endl; << 322 GLint error = GL_NO_ERROR; << 323 while ((error = glGetError()) != GL_NO_ERR << 324 switch (error) { << 325 case GL_INVALID_ENUM : << 326 G4cout << "GL Error: GL_INVALID_ENUM" << G4e << 327 case GL_INVALID_VALUE : << 328 G4cout << "GL Error: GL_INVALID_VALUE" << G4 << 329 case GL_INVALID_OPERATION : << 330 G4cout << "GL Error: GL_INVALID_OPERATION" < << 331 case GL_OUT_OF_MEMORY : << 332 G4cout << "GL Error: GL_OUT_OF_MEMORY" << G4 << 333 case GL_STACK_UNDERFLOW : << 334 G4cout << "GL Error: GL_STACK_UNDERFLOW" << << 335 case GL_STACK_OVERFLOW : << 336 G4cout << "GL Error: GL_STACK_OVERFLOW" << G << 337 default : << 338 G4cout << "GL Error: " << error << G4endl;br << 339 } << 340 } << 341 return; << 342 } << 343 } 281 } 344 282 345 void G4OpenGLXViewer::CreateFontLists() << 346 { << 347 std::map<G4double,G4String> fonts; // G4VMa << 348 fonts[10.] = "-adobe-courier-bold-r-normal-- << 349 fonts[11.] = "-adobe-courier-bold-r-normal-- << 350 fonts[12.] = "-adobe-courier-bold-r-normal-- << 351 fonts[13.] = "fixed"; << 352 fonts[14.] = "-adobe-courier-bold-r-normal-- << 353 fonts[17.] = "-adobe-courier-bold-r-normal-- << 354 fonts[18.] = "-adobe-courier-bold-r-normal-- << 355 fonts[20.] = "-adobe-courier-bold-r-normal-- << 356 fonts[24.] = "-adobe-courier-bold-r-normal-- << 357 fonts[25.] = "-adobe-courier-bold-r-normal-- << 358 fonts[34.] = "-adobe-courier-bold-r-normal-- << 359 std::map<G4double,G4String>::const_iterator << 360 for (i = fonts.begin(); i != fonts.end(); ++ << 361 XFontStruct* font_info = XLoadQueryFont(dp << 362 if (!font_info) { << 363 G4cerr << << 364 "G4OpenGLXViewer::CreateFontLists XLoadQuery << 365 << i->second << 366 << G4endl; << 367 continue; << 368 } << 369 G4int font_base = glGenLists(256); << 370 if (!font_base) { << 371 G4cerr << << 372 "G4OpenGLXViewer::CreateFontLists out of dis << 373 << G4endl; << 374 continue; << 375 } << 376 G4int first = font_info->min_char_or_byte2 << 377 G4int last = font_info->max_char_or_byte2 << 378 glXUseXFont(font_info->fid, first, last-fi << 379 G4int width = font_info->max_bounds.width; << 380 G4OpenGLFontBaseStore::AddFontBase << 381 (this, font_base, i->first, i->second, w << 382 } << 383 } << 384 << 385 void G4OpenGLXViewer::DrawText(const G4Text& g << 386 { << 387 if (isGl2psWriting()) { << 388 << 389 G4OpenGLViewer::DrawText(g4text); << 390 << 391 } else { << 392 << 393 G4VSceneHandler::MarkerSizeType sizeType; << 394 G4double size = fSceneHandler.GetMarkerSiz << 395 << 396 const G4OpenGLFontBaseStore::FontInfo& fon << 397 G4OpenGLFontBaseStore::GetFontInfo(this, << 398 if (fontInfo.fFontBase < 0) { << 399 static G4int callCount = 0; << 400 ++callCount; << 401 //if (callCount <= 10 || callCount%100 = << 402 if (callCount <= 1) { << 403 G4cout << << 404 "G4OpenGLXViewer::DrawText: No fonts avail << 405 << fName << << 406 "\"\n Called with " << 407 << g4text << 408 << G4endl; << 409 } << 410 return; << 411 } << 412 << 413 const G4Colour& c = fSceneHandler.GetTextC << 414 glColor4d(c.GetRed(),c.GetGreen(),c.GetBlu << 415 << 416 G4Point3D position = g4text.GetPosition(); << 417 << 418 G4String textString = g4text.GetText(); << 419 const char* textCString = textString.c_str << 420 << 421 // Set position for raster-style drawers ( << 422 glRasterPos3d(position.x(),position.y(),po << 423 << 424 glPushAttrib(GL_LIST_BIT); << 425 << 426 // Calculate move for centre and right adj << 427 G4double span = textString.size() * fontIn << 428 G4double xmove = 0., ymove = 0.; << 429 switch (g4text.GetLayout()) { << 430 case G4Text::left: break; << 431 case G4Text::centre: xmove -= span / 2.; b << 432 case G4Text::right: xmove -= span; << 433 } << 434 << 435 //Add offsets << 436 xmove += g4text.GetXOffset(); << 437 ymove += g4text.GetYOffset(); << 438 << 439 // Do move << 440 glBitmap(0,0,0,0,xmove,ymove,0); << 441 << 442 // Write characters << 443 glListBase(fontInfo.fFontBase); << 444 glCallLists((G4int)strlen(textCString),GL_ << 445 glPopAttrib(); << 446 } << 447 } << 448 << 449 << 450 G4OpenGLXViewer::G4OpenGLXViewer (G4OpenGLScen 283 G4OpenGLXViewer::G4OpenGLXViewer (G4OpenGLSceneHandler& scene): 451 G4VViewer (scene, -1), 284 G4VViewer (scene, -1), 452 G4OpenGLViewer (scene), 285 G4OpenGLViewer (scene), >> 286 print_colour (true), >> 287 vectored_ps (true), 453 vi_immediate (0), 288 vi_immediate (0), 454 vi_stored (0), << 289 vi_stored (0) 455 vi (0), << 456 cmap (0) << 457 { 290 { 458 // To satisfy Coverity << 291 459 xwa.visual = 0; << 292 strcpy (print_string, "G4OpenGL.eps"); 460 iconName.value = 0; << 461 xwa.screen = 0; << 462 windowName.value = 0; << 463 293 464 GetXConnection (); 294 GetXConnection (); 465 if (fViewId < 0) return; 295 if (fViewId < 0) return; 466 296 467 // Try for a visual suitable for OpenGLImmed 297 // Try for a visual suitable for OpenGLImmediate.. 468 // first try for a single buffered RGB windo 298 // first try for a single buffered RGB window 469 if (!vi_single_buffer) { 299 if (!vi_single_buffer) { 470 vi_single_buffer = 300 vi_single_buffer = 471 glXChooseVisual (dpy, XDefaultScreen (dp 301 glXChooseVisual (dpy, XDefaultScreen (dpy), snglBuf_RGBA); 472 //G.Barrand : we should do a XFree(vi_sing << 473 } 302 } 474 if (!vi_double_buffer) { 303 if (!vi_double_buffer) { 475 vi_double_buffer = 304 vi_double_buffer = 476 glXChooseVisual (dpy, XDefaultScreen (dp 305 glXChooseVisual (dpy, XDefaultScreen (dpy), dblBuf_RGBA); 477 //G.Barrand : we should do a XFree(vi_doub << 478 } 306 } 479 307 480 if (vi_single_buffer || vi_double_buffer) { 308 if (vi_single_buffer || vi_double_buffer) { 481 if (!vi_double_buffer) { 309 if (!vi_double_buffer) { 482 G4cout << 310 G4cout << 483 "G4OpenGLXViewer::G4OpenGLXViewer: unable to 311 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get a double buffer visual." 484 "\n Working with a single buffer." 312 "\n Working with a single buffer." 485 << G4endl; 313 << G4endl; 486 } 314 } 487 } else { 315 } else { 488 if (!vi_single_buffer) { 316 if (!vi_single_buffer) { 489 G4cout << 317 G4cout << 490 "G4OpenGLXViewer::G4OpenGLXViewer: unable to 318 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get a single buffer visual." 491 << G4endl; 319 << G4endl; 492 } 320 } 493 if (!vi_double_buffer) { 321 if (!vi_double_buffer) { 494 G4cout << 322 G4cout << 495 "G4OpenGLXViewer::G4OpenGLXViewer: unable to 323 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get a double buffer visual." 496 << G4endl; 324 << G4endl; 497 } 325 } 498 } 326 } 499 327 500 if (vi_single_buffer) { 328 if (vi_single_buffer) { 501 vi_immediate = vi_single_buffer; 329 vi_immediate = vi_single_buffer; 502 attributeList = snglBuf_RGBA; 330 attributeList = snglBuf_RGBA; >> 331 doublebuffer = false; 503 } 332 } 504 333 505 if (!vi_immediate){ 334 if (!vi_immediate){ 506 // next try for a double buffered RGB, but 335 // next try for a double buffered RGB, but Draw to top buffer 507 if (vi_double_buffer) { 336 if (vi_double_buffer) { 508 vi_immediate = vi_double_buffer; 337 vi_immediate = vi_double_buffer; 509 attributeList = dblBuf_RGBA; 338 attributeList = dblBuf_RGBA; >> 339 doublebuffer = true; 510 } 340 } 511 } 341 } 512 342 513 // Now try for a visual suitable for OpenGLS 343 // Now try for a visual suitable for OpenGLStored... 514 // Try for a double buffered RGB window 344 // Try for a double buffered RGB window 515 if (vi_double_buffer) { 345 if (vi_double_buffer) { 516 vi_stored = vi_double_buffer; 346 vi_stored = vi_double_buffer; 517 attributeList = dblBuf_RGBA; 347 attributeList = dblBuf_RGBA; >> 348 doublebuffer = true; 518 } 349 } 519 350 520 if (!vi_immediate || !vi_stored) { 351 if (!vi_immediate || !vi_stored) { 521 G4cout << 352 G4cout << 522 "G4OpenGLXViewer::G4OpenGLXViewer: unable 353 "G4OpenGLXViewer::G4OpenGLXViewer: unable to get required visuals." 523 << G4endl; 354 << G4endl; 524 fViewId = -1; // This flags an error. 355 fViewId = -1; // This flags an error. 525 } 356 } 526 357 527 // glClearColor (0., 0., 0., 0.); 358 // glClearColor (0., 0., 0., 0.); 528 // glClearDepth (1.); 359 // glClearDepth (1.); >> 360 529 } 361 } 530 362 531 G4OpenGLXViewer::~G4OpenGLXViewer () { 363 G4OpenGLXViewer::~G4OpenGLXViewer () { 532 if (fViewId >= 0) { 364 if (fViewId >= 0) { 533 //Close a window from here 365 //Close a window from here 534 glXMakeCurrent (dpy, None, NULL); 366 glXMakeCurrent (dpy, None, NULL); 535 glXDestroyContext (dpy, cxMaster); << 367 glXDestroyContext (dpy, cx); 536 if (win) XDestroyWindow (dpy, win); // ... 368 if (win) XDestroyWindow (dpy, win); // ...if already deleted in 537 // sub-class G4OpenGLXmViewer. 369 // sub-class G4OpenGLXmViewer. 538 // We should do a XFreeColormap(dpy,cmap); << 539 XFlush (dpy); 370 XFlush (dpy); 540 } 371 } 541 } 372 } 542 << 373 >> 374 void G4OpenGLXViewer::print() { >> 375 >> 376 //using namespace std; >> 377 //cout << "print_col_callback requested with file name: " << print_string << G4endl; >> 378 >> 379 if (vectored_ps) { >> 380 G4int size = 5000000; >> 381 >> 382 GLfloat* feedback_buffer; >> 383 GLint returned; >> 384 FILE* file; >> 385 >> 386 feedback_buffer = new GLfloat[size]; >> 387 glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer); >> 388 glRenderMode (GL_FEEDBACK); >> 389 >> 390 DrawView(); >> 391 returned = glRenderMode (GL_RENDER); >> 392 >> 393 if (print_string) { >> 394 file = fopen (print_string, "w"); >> 395 if (file) { >> 396 spewWireframeEPS (file, returned, feedback_buffer, "rendereps"); >> 397 } else { >> 398 printf("Could not open %s\n", print_string); >> 399 } >> 400 } else { >> 401 printBuffer (returned, feedback_buffer); >> 402 } >> 403 // free (feedback_buffer); >> 404 delete[] feedback_buffer; >> 405 >> 406 } else { >> 407 >> 408 XVisualInfo* pvi; >> 409 G4bool new_db; >> 410 G4bool last_db; >> 411 GLXContext pcx = create_GL_print_context(pvi, new_db); >> 412 GLXContext tmp_cx; >> 413 tmp_cx = cx; >> 414 cx=pcx; >> 415 last_db=doublebuffer; >> 416 doublebuffer=new_db; >> 417 >> 418 Pixmap pmap = XCreatePixmap (dpy, >> 419 XRootWindow (dpy, pvi->screen), >> 420 WinSize_x, WinSize_y, >> 421 pvi->depth); >> 422 >> 423 GLXPixmap glxpmap = glXCreateGLXPixmap (dpy, >> 424 pvi, >> 425 pmap); >> 426 >> 427 GLXDrawable tmp_win; >> 428 tmp_win=win; >> 429 win=glxpmap; >> 430 >> 431 glXMakeCurrent (dpy, >> 432 glxpmap, >> 433 cx); >> 434 >> 435 glViewport (0, 0, WinSize_x, WinSize_y); >> 436 >> 437 ClearView (); >> 438 DrawView (); >> 439 >> 440 generateEPS (print_string, >> 441 print_colour, >> 442 WinSize_x, WinSize_y); >> 443 >> 444 win=tmp_win; >> 445 cx=tmp_cx; >> 446 doublebuffer=last_db; >> 447 >> 448 glXMakeCurrent (dpy, >> 449 glxpmap, >> 450 cx); >> 451 >> 452 } >> 453 >> 454 } >> 455 >> 456 void G4OpenGLXViewer::print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer) >> 457 { >> 458 G4int i; >> 459 >> 460 printf(" "); >> 461 for (i = 0; i < 7; i++) { >> 462 printf("%4.2f ", buffer[size - (*count)]); >> 463 *count = *count - 1; >> 464 } >> 465 printf("\n"); >> 466 } >> 467 >> 468 void G4OpenGLXViewer::spewWireframeEPS (FILE* file, GLint size, GLfloat* buffer, const char* cr) { >> 469 >> 470 GLfloat EPS_GOURAUD_THRESHOLD=0.1; >> 471 >> 472 GLfloat clearColor[4], viewport[4]; >> 473 GLfloat lineWidth; >> 474 G4int i; >> 475 >> 476 glGetFloatv (GL_VIEWPORT, viewport); >> 477 glGetFloatv (GL_COLOR_CLEAR_VALUE, clearColor); >> 478 glGetFloatv (GL_LINE_WIDTH, &lineWidth); >> 479 glGetFloatv (GL_POINT_SIZE, &pointSize); >> 480 >> 481 fputs ("%!PS-Adobe-2.0 EPSF-2.0\n", file); >> 482 fprintf (file, "%%%%Creator: %s (using OpenGL feedback)\n", cr); >> 483 fprintf (file, "%%%%BoundingBox: %g %g %g %g\n", viewport[0], viewport[1], viewport[2], viewport[3]); >> 484 fputs ("%%EndComments\n", file); >> 485 fputs ("\n", file); >> 486 fputs ("gsave\n", file); >> 487 fputs ("\n", file); >> 488 >> 489 fputs ("% the gouraudtriangle PostScript fragment below is free\n", file); >> 490 fputs ("% written by Frederic Delhoume (delhoume@ilog.fr)\n", file); >> 491 fprintf (file, "/threshold %g def\n", EPS_GOURAUD_THRESHOLD); >> 492 for (i=0; gouraudtriangleEPS[i]; i++) { >> 493 fprintf (file, "%s\n", gouraudtriangleEPS[i]); >> 494 } >> 495 >> 496 fprintf(file, "\n%g setlinewidth\n", lineWidth); >> 497 >> 498 fprintf (file, "%g %g %g setrgbcolor\n", clearColor[0], clearColor[1], clearColor[2]); >> 499 fprintf (file, "%g %g %g %g rectfill\n\n", viewport[0], viewport[1], viewport[2], viewport[3]); >> 500 >> 501 spewSortedFeedback (file, size, buffer); >> 502 >> 503 fputs ("grestore\n\n", file); >> 504 fputs ("showpage\n", file); >> 505 >> 506 fclose(file); >> 507 } >> 508 >> 509 void G4OpenGLXViewer::printBuffer (GLint size, GLfloat* buffer) { >> 510 >> 511 GLint count; >> 512 G4int token, nvertices; >> 513 >> 514 count=size; >> 515 while(count) { >> 516 token=G4int (buffer[size-count]); >> 517 count--; >> 518 switch (token) { >> 519 >> 520 case GL_PASS_THROUGH_TOKEN: >> 521 printf ("GL_PASS_THROUGH_TOKEN\n"); >> 522 printf (" %4.2f\n", buffer[size-count]); >> 523 count--; >> 524 break; >> 525 >> 526 case GL_POINT_TOKEN: >> 527 printf ("GL_POINT_TOKEN\n"); >> 528 print3DcolorVertex (size, &count, buffer); >> 529 break; >> 530 >> 531 case GL_LINE_TOKEN: >> 532 printf ("GL_LINE_TOKEN\n"); >> 533 print3DcolorVertex (size, &count, buffer); >> 534 print3DcolorVertex (size, &count, buffer); >> 535 break; >> 536 >> 537 case GL_LINE_RESET_TOKEN: >> 538 printf ("GL_LINE_RESET_TOKEN\n"); >> 539 print3DcolorVertex (size, &count, buffer); >> 540 print3DcolorVertex (size, &count, buffer); >> 541 break; >> 542 >> 543 case GL_POLYGON_TOKEN: >> 544 printf ("GL_POLYGON_TOKEN\n"); >> 545 nvertices=G4int (buffer[size-count]); >> 546 count--; >> 547 for (; nvertices>0; nvertices--) { >> 548 print3DcolorVertex (size, &count, buffer); >> 549 } >> 550 } >> 551 } >> 552 } >> 553 >> 554 G4float* G4OpenGLXViewer::spewPrimitiveEPS (FILE* file, GLfloat* loc) { >> 555 >> 556 G4int token; >> 557 G4int nvertices, i; >> 558 GLfloat red, green, blue, intensity; >> 559 G4int smooth; >> 560 GLfloat dx, dy, dr, dg, db, absR, absG, absB, colormax; >> 561 G4int steps; >> 562 Feedback3Dcolor *vertex; >> 563 GLfloat xstep(0.), ystep(0.), rstep(0.), gstep(0.), bstep(0.); >> 564 GLfloat xnext(0.), ynext(0.), rnext(0.), gnext(0.), bnext(0.), distance(0.); >> 565 >> 566 token=G4int (*loc); >> 567 loc++; >> 568 switch (token) { >> 569 case GL_LINE_RESET_TOKEN: >> 570 case GL_LINE_TOKEN: >> 571 vertex=(Feedback3Dcolor*)loc; >> 572 dr=vertex[1].red - vertex[0].red; >> 573 dg=vertex[1].green - vertex[0].green; >> 574 db=vertex[1].blue - vertex[0].blue; >> 575 >> 576 if (!print_colour) { >> 577 dr+=(dg+db); >> 578 dr/=3.0; >> 579 dg=dr; >> 580 db=dr; >> 581 } >> 582 >> 583 if (dr!=0 || dg!=0 || db!=0) { >> 584 dx=vertex[1].x - vertex[0].x; >> 585 dy=vertex[1].y - vertex[0].y; >> 586 distance=std::sqrt(dx*dx + dy*dy); >> 587 >> 588 absR=std::fabs(dr); >> 589 absG=std::fabs(dg); >> 590 absB=std::fabs(db); >> 591 >> 592 #define Max(a, b) (((a)>(b))?(a):(b)) >> 593 >> 594 #define EPS_SMOOTH_LINE_FACTOR 0.06 >> 595 >> 596 colormax=Max(absR, Max(absG, absB)); >> 597 steps=Max(1, G4int (colormax*distance*EPS_SMOOTH_LINE_FACTOR)); >> 598 >> 599 xstep=dx/steps; >> 600 ystep=dy/steps; >> 601 >> 602 rstep=dr/steps; >> 603 gstep=dg/steps; >> 604 bstep=db/steps; >> 605 >> 606 xnext=vertex[0].x; >> 607 ynext=vertex[0].y; >> 608 rnext=vertex[0].red; >> 609 gnext=vertex[0].green; >> 610 bnext=vertex[0].blue; >> 611 >> 612 if (!print_colour) { >> 613 rnext+=(gnext+bnext); >> 614 rnext/=3.0; >> 615 gnext=rnext; >> 616 bnext=rnext; >> 617 } >> 618 >> 619 xnext -= xstep/2.0; >> 620 ynext -= ystep/2.0; >> 621 rnext -= rstep/2.0; >> 622 gnext -= gstep/2.0; >> 623 bnext -= bstep/2.0; >> 624 } else { >> 625 steps=0; >> 626 } >> 627 if (print_colour) { >> 628 fprintf (file, "%g %g %g setrgbcolor\n", >> 629 vertex[0].red, vertex[0].green, vertex[0].blue); >> 630 } else { >> 631 intensity = (vertex[0].red + vertex[0].green + vertex[0].blue) / 3.0; >> 632 fprintf (file, "%g %g %g setrgbcolor\n", >> 633 intensity, intensity, intensity); >> 634 } >> 635 fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y); >> 636 >> 637 for (i=0; i<steps; i++) { >> 638 >> 639 xnext += xstep; >> 640 ynext += ystep; >> 641 rnext += rstep; >> 642 gnext += gstep; >> 643 bnext += bstep; >> 644 >> 645 fprintf (file, "%g %g lineto stroke\n", xnext, ynext); >> 646 fprintf (file, "%g %g %g setrgbcolor\n", rnext, gnext, bnext); >> 647 fprintf (file, "%g %g moveto\n", xnext, ynext); >> 648 } >> 649 fprintf (file, "%g %g lineto stroke\n", vertex[1].x, vertex[1].y); >> 650 >> 651 loc += 14; >> 652 break; >> 653 >> 654 case GL_POLYGON_TOKEN: >> 655 nvertices = G4int (*loc); >> 656 loc++; >> 657 vertex=(Feedback3Dcolor*)loc; >> 658 if (nvertices>0) { >> 659 red=vertex[0].red; >> 660 green=vertex[0].green; >> 661 blue=vertex[0].blue; >> 662 smooth=0; >> 663 >> 664 if (!print_colour) { >> 665 red+=(green+blue); >> 666 red/=3.0; >> 667 green=red; >> 668 blue=red; >> 669 } >> 670 >> 671 if (print_colour) { >> 672 for (i=1; i<nvertices; i++) { >> 673 if (red!=vertex[i].red || green!=vertex[i].green || blue!=vertex[i].blue) { >> 674 smooth=1; >> 675 break; >> 676 } >> 677 } >> 678 } else { >> 679 for (i=1; i<nvertices; i++) { >> 680 intensity = vertex[i].red + vertex[i].green + vertex[i].blue; >> 681 intensity/=3.0; >> 682 if (red!=intensity) { >> 683 smooth=1; >> 684 break; >> 685 } >> 686 } >> 687 } >> 688 >> 689 if (smooth) { >> 690 G4int triOffset; >> 691 for (i=0; i<nvertices-2; i++) { >> 692 triOffset = i*7; >> 693 fprintf (file, "[%g %g %g %g %g %g]", >> 694 vertex[0].x, vertex[i+1].x, vertex[i+2].x, >> 695 vertex[0].y, vertex[i+1].y, vertex[i+2].y); >> 696 if (print_colour) { >> 697 fprintf (file, " [%g %g %g] [%g %g %g] [%g %g %g] gouraudtriangle\n", >> 698 vertex[0].red, vertex[0].green, vertex[0].blue, >> 699 vertex[i+1].red, vertex[i+1].green, vertex[i+1].blue, >> 700 vertex[i+2].red, vertex[i+2].green, vertex[i+2].blue); >> 701 } else { >> 702 >> 703 intensity = vertex[0].red + vertex[0].green + vertex[0].blue; >> 704 intensity/=3.0; >> 705 fprintf (file, " [%g %g %g]", intensity, intensity, intensity); >> 706 >> 707 intensity = vertex[1].red + vertex[1].green + vertex[1].blue; >> 708 intensity/=3.0; >> 709 fprintf (file, " [%g %g %g]", intensity, intensity, intensity); >> 710 >> 711 intensity = vertex[2].red + vertex[2].green + vertex[2].blue; >> 712 intensity/=3.0; >> 713 fprintf (file, " [%g %g %g] gouraudtriangle\n", intensity, intensity, intensity); >> 714 } >> 715 } >> 716 } else { >> 717 fprintf (file, "newpath\n"); >> 718 fprintf (file, "%g %g %g setrgbcolor\n", red, green, blue); >> 719 fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y); >> 720 for (i=1; i<nvertices; i++) { >> 721 fprintf (file, "%g %g lineto\n", vertex[i].x, vertex[i].y); >> 722 } >> 723 fprintf (file, "closepath fill\n\n"); >> 724 } >> 725 } >> 726 loc += nvertices*7; >> 727 break; >> 728 >> 729 case GL_POINT_TOKEN: >> 730 vertex=(Feedback3Dcolor*)loc; >> 731 if (print_colour) { >> 732 fprintf (file, "%g %g %g setrgbcolor\n", vertex[0].red, vertex[0].green, vertex[0].blue); >> 733 } else { >> 734 intensity = vertex[0].red + vertex[0].green + vertex[0].blue; >> 735 intensity/=3.0; >> 736 fprintf (file, "%g %g %g setrgbcolor\n", intensity, intensity, intensity); >> 737 } >> 738 fprintf(file, "%g %g %g 0 360 arc fill\n\n", vertex[0].x, vertex[0].y, pointSize / 2.0); >> 739 loc += 7; /* Each vertex element in the feedback >> 740 buffer is 7 GLfloats. */ >> 741 break; >> 742 default: >> 743 /* XXX Left as an excersie to the reader. */ >> 744 printf("Incomplete implementation. Unexpected token (%d).\n", token); >> 745 exit(1); >> 746 } >> 747 return loc; >> 748 } >> 749 >> 750 typedef struct G4OpenGLXViewerDepthIndex { >> 751 GLfloat *ptr; >> 752 GLfloat depth; >> 753 } DepthIndex; >> 754 >> 755 extern "C" { >> 756 int G4OpenGLXViewercompare(const void *a, const void *b) >> 757 { >> 758 const DepthIndex *p1 = (DepthIndex *) a; >> 759 const DepthIndex *p2 = (DepthIndex *) b; >> 760 GLfloat diff = p2->depth - p1->depth; >> 761 >> 762 if (diff > 0.0) { >> 763 return 1; >> 764 } else if (diff < 0.0) { >> 765 return -1; >> 766 } else { >> 767 return 0; >> 768 } >> 769 } >> 770 } >> 771 >> 772 void G4OpenGLXViewer::spewSortedFeedback(FILE * file, GLint size, GLfloat * buffer) >> 773 { >> 774 int token; >> 775 GLfloat *loc, *end; >> 776 Feedback3Dcolor *vertex; >> 777 GLfloat depthSum; >> 778 int nprimitives, item; >> 779 DepthIndex *prims; >> 780 int nvertices, i; >> 781 >> 782 end = buffer + size; >> 783 >> 784 /* Count how many primitives there are. */ >> 785 nprimitives = 0; >> 786 loc = buffer; >> 787 while (loc < end) { >> 788 token = int (*loc); >> 789 loc++; >> 790 switch (token) { >> 791 case GL_LINE_TOKEN: >> 792 case GL_LINE_RESET_TOKEN: >> 793 loc += 14; >> 794 nprimitives++; >> 795 break; >> 796 case GL_POLYGON_TOKEN: >> 797 nvertices = int (*loc); >> 798 loc++; >> 799 loc += (7 * nvertices); >> 800 nprimitives++; >> 801 break; >> 802 case GL_POINT_TOKEN: >> 803 loc += 7; >> 804 nprimitives++; >> 805 break; >> 806 default: >> 807 /* XXX Left as an excersie to the reader. */ >> 808 printf("Incomplete implementation. Unexpected token (%d).\n", >> 809 token); >> 810 exit(1); >> 811 } >> 812 } >> 813 >> 814 /* Allocate an array of pointers that will point back at >> 815 primitives in the feedback buffer. There will be one >> 816 entry per primitive. This array is also where we keep the >> 817 primitive's average depth. There is one entry per >> 818 primitive in the feedback buffer. */ >> 819 prims = (DepthIndex *) malloc(sizeof(DepthIndex) * nprimitives); >> 820 >> 821 item = 0; >> 822 loc = buffer; >> 823 while (loc < end) { >> 824 prims[item].ptr = loc; /* Save this primitive's location. */ >> 825 token = int (*loc); >> 826 loc++; >> 827 switch (token) { >> 828 case GL_LINE_TOKEN: >> 829 case GL_LINE_RESET_TOKEN: >> 830 vertex = (Feedback3Dcolor *) loc; >> 831 depthSum = vertex[0].z + vertex[1].z; >> 832 prims[item].depth = depthSum / 2.0; >> 833 loc += 14; >> 834 break; >> 835 case GL_POLYGON_TOKEN: >> 836 nvertices = int (*loc); >> 837 loc++; >> 838 vertex = (Feedback3Dcolor *) loc; >> 839 depthSum = vertex[0].z; >> 840 for (i = 1; i < nvertices; i++) { >> 841 depthSum += vertex[i].z; >> 842 } >> 843 prims[item].depth = depthSum / nvertices; >> 844 loc += (7 * nvertices); >> 845 break; >> 846 case GL_POINT_TOKEN: >> 847 vertex = (Feedback3Dcolor *) loc; >> 848 prims[item].depth = vertex[0].z; >> 849 loc += 7; >> 850 break; >> 851 default: >> 852 /* XXX Left as an excersie to the reader. */ >> 853 assert(1); >> 854 } >> 855 item++; >> 856 } >> 857 assert(item == nprimitives); >> 858 >> 859 /* Sort the primitives back to front. */ >> 860 qsort(prims, nprimitives, sizeof(DepthIndex), G4OpenGLXViewercompare); >> 861 >> 862 /* Understand that sorting by a primitives average depth >> 863 doesn't allow us to disambiguate some cases like self >> 864 intersecting polygons. Handling these cases would require >> 865 breaking up the primitives. That's too involved for this >> 866 example. Sorting by depth is good enough for lots of >> 867 applications. */ >> 868 >> 869 /* Emit the Encapsulated PostScript for the primitives in >> 870 back to front order. */ >> 871 for (item = 0; item < nprimitives; item++) { >> 872 (void) spewPrimitiveEPS(file, prims[item].ptr); >> 873 } >> 874 >> 875 free(prims); >> 876 } >> 877 >> 878 GLXContext G4OpenGLXViewer::create_GL_print_context(XVisualInfo*& pvi, G4bool& db) { >> 879 >> 880 pvi = glXChooseVisual (dpy, >> 881 XDefaultScreen (dpy), >> 882 snglBuf_RGBA); >> 883 >> 884 if (pvi) { >> 885 db=false; >> 886 } else { >> 887 pvi = glXChooseVisual (dpy, >> 888 XDefaultScreen (dpy), >> 889 dblBuf_RGBA); >> 890 if (!pvi) { >> 891 db=true; >> 892 } >> 893 } >> 894 >> 895 return glXCreateContext (dpy, >> 896 pvi, >> 897 NULL, >> 898 False); >> 899 } >> 900 >> 901 int G4OpenGLXViewer::generateEPS (char* filnam, >> 902 int inColour, >> 903 unsigned int width, >> 904 unsigned int height) { >> 905 >> 906 FILE* fp; >> 907 GLubyte* pixels; >> 908 GLubyte* curpix; >> 909 int components, pos, i; >> 910 >> 911 pixels = grabPixels (inColour, width, height); >> 912 >> 913 if (pixels == NULL) >> 914 return 1; >> 915 if (inColour) { >> 916 components = 3; >> 917 } else { >> 918 components = 1; >> 919 } >> 920 >> 921 fp = fopen (filnam, "w"); >> 922 if (fp == NULL) { >> 923 return 2; >> 924 } >> 925 >> 926 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n"); >> 927 fprintf (fp, "%%%%Title: %s\n", filnam); >> 928 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n"); >> 929 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height); >> 930 fprintf (fp, "%%%%EndComments\n"); >> 931 fprintf (fp, "gsave\n"); >> 932 fprintf (fp, "/bwproc {\n"); >> 933 fprintf (fp, " rgbproc\n"); >> 934 fprintf (fp, " dup length 3 idiv string 0 3 0 \n"); >> 935 fprintf (fp, " 5 -1 roll {\n"); >> 936 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n"); >> 937 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n"); >> 938 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n"); >> 939 fprintf (fp, " { 2 1 roll } ifelse\n"); >> 940 fprintf (fp, " }forall\n"); >> 941 fprintf (fp, " pop pop pop\n"); >> 942 fprintf (fp, "} def\n"); >> 943 fprintf (fp, "systemdict /colorimage known not {\n"); >> 944 fprintf (fp, " /colorimage {\n"); >> 945 fprintf (fp, " pop\n"); >> 946 fprintf (fp, " pop\n"); >> 947 fprintf (fp, " /rgbproc exch def\n"); >> 948 fprintf (fp, " { bwproc } image\n"); >> 949 fprintf (fp, " } def\n"); >> 950 fprintf (fp, "} if\n"); >> 951 fprintf (fp, "/picstr %d string def\n", width * components); >> 952 fprintf (fp, "%d %d scale\n", width, height); >> 953 fprintf (fp, "%d %d %d\n", width, height, 8); >> 954 fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height); >> 955 fprintf (fp, "{currentfile picstr readhexstring pop}\n"); >> 956 fprintf (fp, "false %d\n", components); >> 957 fprintf (fp, "colorimage\n"); >> 958 >> 959 curpix = (GLubyte*) pixels; >> 960 pos = 0; >> 961 for (i = width*height*components; i>0; i--) { >> 962 fprintf (fp, "%02hx ", *(curpix++)); >> 963 if (++pos >= 32) { >> 964 fprintf (fp, "\n"); >> 965 pos = 0; >> 966 } >> 967 } >> 968 if (pos) >> 969 fprintf (fp, "\n"); >> 970 >> 971 fprintf (fp, "grestore\n"); >> 972 fprintf (fp, "showpage\n"); >> 973 delete pixels; >> 974 fclose (fp); >> 975 return 0; >> 976 } >> 977 >> 978 GLubyte* G4OpenGLXViewer::grabPixels (int inColor, unsigned int width, unsigned int height) { >> 979 >> 980 GLubyte* buffer; >> 981 GLint swapbytes, lsbfirst, rowlength; >> 982 GLint skiprows, skippixels, alignment; >> 983 GLenum format; >> 984 int size; >> 985 >> 986 if (inColor) { >> 987 format = GL_RGB; >> 988 size = width*height*3; >> 989 } else { >> 990 format = GL_LUMINANCE; >> 991 size = width*height*1; >> 992 } >> 993 >> 994 buffer = new GLubyte[size]; >> 995 if (buffer == NULL) >> 996 return NULL; >> 997 >> 998 glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes); >> 999 glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst); >> 1000 glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength); >> 1001 >> 1002 glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows); >> 1003 glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels); >> 1004 glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment); >> 1005 >> 1006 glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); >> 1007 glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); >> 1008 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); >> 1009 >> 1010 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); >> 1011 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); >> 1012 glPixelStorei (GL_UNPACK_ALIGNMENT, 1); >> 1013 >> 1014 glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer); >> 1015 >> 1016 glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes); >> 1017 glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst); >> 1018 glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength); >> 1019 >> 1020 glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows); >> 1021 glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels); >> 1022 glPixelStorei (GL_UNPACK_ALIGNMENT, alignment); >> 1023 >> 1024 return buffer; >> 1025 } >> 1026 >> 1027 #endif 543 1028