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: G4OpenGLViewer.cc,v 1.14 2002/10/16 10:44:16 johna Exp $ >> 25 // GEANT4 tag $Name: geant4-05-00 $ 27 // 26 // 28 // 27 // 29 // Andrew Walkden 27th March 1996 28 // Andrew Walkden 27th March 1996 30 // OpenGL view - opens window, hard copy, etc. 29 // OpenGL view - opens window, hard copy, etc. 31 30 32 #include "G4ios.hh" << 31 #ifdef G4VIS_BUILD_OPENGL_DRIVER 33 #include <CLHEP/Units/SystemOfUnits.h> << 32 >> 33 #include <GL/gl.h> >> 34 #include <GL/glu.h> >> 35 34 #include "G4OpenGLViewer.hh" 36 #include "G4OpenGLViewer.hh" 35 #include "G4OpenGLSceneHandler.hh" 37 #include "G4OpenGLSceneHandler.hh" 36 #include "G4OpenGLTransform3D.hh" 38 #include "G4OpenGLTransform3D.hh" 37 << 39 #include "G4ios.hh" 38 #include "G4gl2ps.hh" << 39 #define GL2PS_TEXT_B TOOLS_GL2PS_TEXT_B << 40 #define GL2PS_TEXT_BL TOOLS_GL2PS_TEXT_BL << 41 #define GL2PS_TEXT_BR TOOLS_GL2PS_TEXT_BR << 42 40 43 #include "G4Scene.hh" 41 #include "G4Scene.hh" 44 #include "G4VisExtent.hh" 42 #include "G4VisExtent.hh" 45 #include "G4LogicalVolume.hh" 43 #include "G4LogicalVolume.hh" 46 #include "G4VSolid.hh" 44 #include "G4VSolid.hh" 47 #include "G4Point3D.hh" 45 #include "G4Point3D.hh" 48 #include "G4Normal3D.hh" 46 #include "G4Normal3D.hh" 49 #include "G4Plane3D.hh" 47 #include "G4Plane3D.hh" 50 #include "G4AttHolder.hh" << 51 #include "G4AttCheck.hh" << 52 #include "G4Text.hh" << 53 << 54 #include <sstream> << 55 #include <string> << 56 #include <iomanip> << 57 48 58 G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneH 49 G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene): 59 G4VViewer (scene, -1), 50 G4VViewer (scene, -1), 60 fPrintColour (true), << 51 white_background (false), 61 fVectoredPs (true), << 52 transparency_enabled (false), 62 fOpenGLSceneHandler(scene), << 63 background (G4Colour(0.,0.,0.)), << 64 transparency_enabled (true), << 65 antialiasing_enabled (false), 53 antialiasing_enabled (false), 66 haloing_enabled (false), << 54 haloing_enabled (false) 67 fRot_sens(1.), << 68 fPan_sens(0.01), << 69 fWinSize_x(0), << 70 fWinSize_y(0), << 71 fDefaultExportImageFormat("pdf"), << 72 fExportImageFormat("pdf"), << 73 fExportFilenameIndex(0), << 74 fPrintSizeX(-1), << 75 fPrintSizeY(-1), << 76 fPointSize (0), << 77 fDefaultExportFilename("G4OpenGL"), << 78 fSizeHasChanged(0), << 79 fGl2psDefaultLineWith(1), << 80 fGl2psDefaultPointSize(2), << 81 fGlViewInitialized(false), << 82 fIsGettingPickInfos(false) << 83 { 55 { 84 // Make changes to view parameters for OpenG 56 // Make changes to view parameters for OpenGL... 85 fVP.SetAutoRefresh(true); 57 fVP.SetAutoRefresh(true); 86 fDefaultVP.SetAutoRefresh(true); 58 fDefaultVP.SetAutoRefresh(true); 87 fGL2PSAction = new G4gl2ps(); << 88 tools_gl2ps_gl_funcs_t _funcs = { << 89 (tools_glIsEnabled_func)glIsEnabled, << 90 (tools_glBegin_func)glBegin, << 91 (tools_glEnd_func)glEnd, << 92 (tools_glGetFloatv_func)glGetFloatv, << 93 (tools_glVertex3f_func)glVertex3f, << 94 (tools_glGetBooleanv_func)glGetBooleanv, << 95 (tools_glGetIntegerv_func)glGetIntegerv, << 96 (tools_glRenderMode_func)glRenderMode, << 97 (tools_glFeedbackBuffer_func)glFeedbackBuf << 98 (tools_glPassThrough_func)glPassThrough << 99 }; << 100 fGL2PSAction->setOpenGLFunctions(&_funcs); << 101 << 102 // add supported export image format << 103 addExportImageFormat("eps"); << 104 addExportImageFormat("ps"); << 105 addExportImageFormat("pdf"); << 106 addExportImageFormat("svg"); << 107 59 108 // Change the default name << 109 fExportFilename += fDefaultExportFilename + << 110 << 111 // glClearColor (0.0, 0.0, 0.0, 0.0); 60 // glClearColor (0.0, 0.0, 0.0, 0.0); 112 // glClearDepth (1.0); 61 // glClearDepth (1.0); 113 // glDisable (GL_BLEND); 62 // glDisable (GL_BLEND); 114 // glDisable (GL_LINE_SMOOTH); 63 // glDisable (GL_LINE_SMOOTH); 115 // glDisable (GL_POLYGON_SMOOTH); 64 // glDisable (GL_POLYGON_SMOOTH); 116 65 117 } 66 } 118 67 119 G4OpenGLViewer::~G4OpenGLViewer () << 68 G4OpenGLViewer::~G4OpenGLViewer () {} 120 { << 121 delete fGL2PSAction; << 122 } << 123 69 124 void G4OpenGLViewer::InitializeGLView () 70 void G4OpenGLViewer::InitializeGLView () 125 { 71 { 126 if (fWinSize_x == 0) { << 127 fWinSize_x = fVP.GetWindowSizeHintX(); << 128 } << 129 if (fWinSize_y == 0) { << 130 fWinSize_y = fVP.GetWindowSizeHintY(); << 131 } << 132 << 133 glClearColor (0.0, 0.0, 0.0, 0.0); 72 glClearColor (0.0, 0.0, 0.0, 0.0); 134 glClearDepth (1.0); 73 glClearDepth (1.0); >> 74 glDisable (GL_BLEND); 135 glDisable (GL_LINE_SMOOTH); 75 glDisable (GL_LINE_SMOOTH); 136 glDisable (GL_POLYGON_SMOOTH); 76 glDisable (GL_POLYGON_SMOOTH); 137 << 77 } 138 // clear the buffers and window? << 139 ClearView (); << 140 FinishView (); << 141 << 142 glDepthFunc (GL_LEQUAL); << 143 glDepthMask (GL_TRUE); << 144 << 145 glEnable (GL_BLEND); << 146 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ << 147 << 148 } << 149 78 150 void G4OpenGLViewer::ClearView () { 79 void G4OpenGLViewer::ClearView () { 151 ClearViewWithoutFlush(); << 80 //Below line does not compile with Mesa includes. 152 << 81 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 153 if(!isFramebufferReady()) { << 154 return; << 155 } << 156 << 157 glFlush(); << 158 } << 159 << 160 << 161 void G4OpenGLViewer::ClearViewWithoutFlush () << 162 // Ready for clear ? << 163 // See : http://lists.apple.com/archives/mac << 164 if(!isFramebufferReady()) { << 165 return; << 166 } << 167 << 168 glClearColor (background.GetRed(), << 169 background.GetGreen(), << 170 background.GetBlue(), << 171 1.); << 172 glClearDepth (1.0); << 173 //Below line does not compile with Mesa incl << 174 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BU << 175 glClear (GL_COLOR_BUFFER_BIT); 82 glClear (GL_COLOR_BUFFER_BIT); 176 glClear (GL_DEPTH_BUFFER_BIT); 83 glClear (GL_DEPTH_BUFFER_BIT); 177 glClear (GL_STENCIL_BUFFER_BIT); 84 glClear (GL_STENCIL_BUFFER_BIT); >> 85 glFlush (); 178 } 86 } 179 87 180 << 181 void G4OpenGLViewer::ResizeWindow(unsigned int << 182 if ((fWinSize_x != aWidth) || (fWinSize_y != << 183 fWinSize_x = aWidth; << 184 fWinSize_y = aHeight; << 185 fSizeHasChanged = true; << 186 } else { << 187 fSizeHasChanged = false; << 188 } << 189 } << 190 << 191 /** << 192 * Set the viewport of the scene << 193 * MAXIMUM SIZE is : << 194 * GLint dims[2]; << 195 * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); << 196 */ << 197 void G4OpenGLViewer::ResizeGLView() << 198 { << 199 // Check size << 200 GLint dims[2]; << 201 dims[0] = 0; << 202 dims[1] = 0; << 203 << 204 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); << 205 << 206 if ((dims[0] !=0 ) && (dims[1] !=0)) { << 207 << 208 if (fWinSize_x > (unsigned)dims[0]) { << 209 G4cerr << "Try to resize view greater th << 210 fWinSize_x = dims[0]; << 211 } << 212 if (fWinSize_y > (unsigned)dims[1]) { << 213 G4cerr << "Try to resize view greater th << 214 fWinSize_y = dims[1]; << 215 } << 216 } << 217 << 218 glViewport(0, 0, fWinSize_x,fWinSize_y); << 219 << 220 << 221 } << 222 << 223 << 224 void G4OpenGLViewer::SetView () { 88 void G4OpenGLViewer::SetView () { 225 // if getting pick infos, should not resize << 226 if (fIsGettingPickInfos) return; << 227 89 228 if (!fSceneHandler.GetScene()) { << 229 return; << 230 } << 231 // Calculates view representation based on e 90 // Calculates view representation based on extent of object being 232 // viewed and (initial) viewpoint. (Note: i 91 // viewed and (initial) viewpoint. (Note: it can change later due 233 // to user interaction via visualization sys 92 // to user interaction via visualization system's GUI.) 234 93 235 // Lighting. 94 // Lighting. 236 GLfloat lightPosition [4]; 95 GLfloat lightPosition [4]; 237 lightPosition [0] = fVP.GetActualLightpointD 96 lightPosition [0] = fVP.GetActualLightpointDirection().x(); 238 lightPosition [1] = fVP.GetActualLightpointD 97 lightPosition [1] = fVP.GetActualLightpointDirection().y(); 239 lightPosition [2] = fVP.GetActualLightpointD 98 lightPosition [2] = fVP.GetActualLightpointDirection().z(); 240 lightPosition [3] = 0.; 99 lightPosition [3] = 0.; 241 // Light position is "true" light direction, 100 // Light position is "true" light direction, so must come after gluLookAt. 242 GLfloat ambient [] = { 0.2f, 0.2f, 0.2f, 1.f << 101 GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.}; 243 GLfloat diffuse [] = { 0.8f, 0.8f, 0.8f, 1.f << 102 GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.}; 244 glEnable (GL_LIGHT0); 103 glEnable (GL_LIGHT0); 245 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); 104 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); 246 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse); 105 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse); 247 106 248 G4double ratioX = 1; << 249 G4double ratioY = 1; << 250 if (fWinSize_y > fWinSize_x) { << 251 ratioX = ((G4double)fWinSize_y) / ((G4doub << 252 } << 253 if (fWinSize_x > fWinSize_y) { << 254 ratioY = ((G4double)fWinSize_x) / ((G4doub << 255 } << 256 << 257 // Get radius of scene, etc. 107 // Get radius of scene, etc. 258 // Note that this procedure properly takes i 108 // Note that this procedure properly takes into account zoom, dolly and pan. 259 const G4Point3D targetPoint 109 const G4Point3D targetPoint 260 = fSceneHandler.GetScene()->GetStandardTar 110 = fSceneHandler.GetScene()->GetStandardTargetPoint() 261 + fVP.GetCurrentTargetPoint (); 111 + fVP.GetCurrentTargetPoint (); 262 G4double radius = fSceneHandler.GetScene()-> 112 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius(); 263 if(radius<=0.) radius = 1.; 113 if(radius<=0.) radius = 1.; 264 const G4double cameraDistance = fVP.GetCamer 114 const G4double cameraDistance = fVP.GetCameraDistance (radius); 265 const G4Point3D cameraPosition = 115 const G4Point3D cameraPosition = 266 targetPoint + cameraDistance * fVP.GetView 116 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit(); 267 const GLdouble pnear = fVP.GetNearDistance << 117 const GLdouble near = fVP.GetNearDistance (cameraDistance, radius); 268 const GLdouble pfar = fVP.GetFarDistance << 118 const GLdouble far = fVP.GetFarDistance (cameraDistance, near, radius); 269 const GLdouble right = fVP.GetFrontHalfHeig << 119 const GLdouble right = fVP.GetFrontHalfHeight (near, radius); 270 const GLdouble left = -right; 120 const GLdouble left = -right; 271 const GLdouble top = fVP.GetFrontHalfHeig << 121 const GLdouble bottom = left; 272 const GLdouble bottom = -top; << 122 const GLdouble top = right; 273 123 274 // FIXME << 275 ResizeGLView(); << 276 //SHOULD SetWindowsSizeHint()... << 277 << 278 glMatrixMode (GL_PROJECTION); // set up Frus 124 glMatrixMode (GL_PROJECTION); // set up Frustum. 279 glLoadIdentity(); 125 glLoadIdentity(); 280 << 281 const G4Vector3D scaleFactor = fVP.GetScaleF << 282 glScaled(scaleFactor.x(),scaleFactor.y(),sca << 283 126 284 if (fVP.GetFieldHalfAngle() == 0.) { 127 if (fVP.GetFieldHalfAngle() == 0.) { 285 g4GlOrtho (left, right, bottom, top, pnear << 128 glOrtho (left, right, bottom, top, near, far); 286 } 129 } 287 else { 130 else { 288 g4GlFrustum (left, right, bottom, top, pne << 131 glFrustum (left, right, bottom, top, near, far); 289 } << 132 } 290 << 133 291 glMatrixMode (GL_MODELVIEW); // apply furthe 134 glMatrixMode (GL_MODELVIEW); // apply further transformations to scene. 292 glLoadIdentity(); 135 glLoadIdentity(); 293 136 294 const G4Normal3D& upVector = fVP.GetUpVector 137 const G4Normal3D& upVector = fVP.GetUpVector (); 295 G4Point3D gltarget; 138 G4Point3D gltarget; 296 if (cameraDistance > 1.e-6 * radius) { 139 if (cameraDistance > 1.e-6 * radius) { 297 gltarget = targetPoint; 140 gltarget = targetPoint; 298 } 141 } 299 else { 142 else { 300 gltarget = targetPoint - radius * fVP.GetV 143 gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit(); 301 } 144 } 302 145 303 const G4Point3D& pCamera = cameraPosition; 146 const G4Point3D& pCamera = cameraPosition; // An alias for brevity. 304 << 147 gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint. 305 g4GluLookAt (pCamera.x(), pCamera.y(), pCa << 148 gltarget.x(), gltarget.y(), gltarget.z(), // Target point. 306 gltarget.x(), gltarget.y(), gltar << 149 upVector.x(), upVector.y(), upVector.z()); // Up vector. 307 upVector.x(), upVector.y(), upVec << 150 308 // Light position is "true" light direction, 151 // Light position is "true" light direction, so must come after gluLookAt. 309 glLightfv (GL_LIGHT0, GL_POSITION, lightPosi 152 glLightfv (GL_LIGHT0, GL_POSITION, lightPosition); 310 153 311 // The idea is to use back-to-back clipping << 154 // Clip planes. 312 // down to just a few pixels, which can make << 155 if (fVP.IsSection () ) { // pair of back to back clip planes. 313 // now, comment this out and use the generic << 156 const G4Plane3D& s = fVP.GetSectionPlane (); 314 // G4VSolid* G4OpenGLSceneHandler::CreateSec << 157 double sArray[4]; 315 // { return G4VSceneHandler::CreateSectionSo << 158 sArray[0] = s.a(); 316 // if (fVP.IsSection () ) { // pair of back << 159 sArray[1] = s.b(); 317 // const G4Plane3D& sp = fVP.GetSectionPlan << 160 sArray[2] = s.c(); 318 // double sArray[4]; << 161 sArray[3] = s.d() + radius * 1.e-05; 319 // sArray[0] = sp.a(); << 162 glClipPlane (GL_CLIP_PLANE0, sArray); 320 // sArray[1] = sp.b(); << 163 glEnable (GL_CLIP_PLANE0); 321 // sArray[2] = sp.c(); << 164 sArray[0] = -s.a(); 322 // sArray[3] = sp.d() + radius * 1.e-05; << 165 sArray[1] = -s.b(); 323 // glClipPlane (GL_CLIP_PLANE0, sArray); << 166 sArray[2] = -s.c(); 324 // glEnable (GL_CLIP_PLANE0); << 167 sArray[3] = -s.d() + radius * 1.e-05; 325 // sArray[0] = -sp.a(); << 168 glClipPlane (GL_CLIP_PLANE1, sArray); 326 // sArray[1] = -sp.b(); << 169 glEnable (GL_CLIP_PLANE1); 327 // sArray[2] = -sp.c(); << 328 // sArray[3] = -sp.d() + radius * 1.e-05; << 329 // glClipPlane (GL_CLIP_PLANE1, sArray); << 330 // glEnable (GL_CLIP_PLANE1); << 331 // } else { << 332 // glDisable (GL_CLIP_PLANE0); << 333 // glDisable (GL_CLIP_PLANE1); << 334 // } << 335 << 336 // What we call intersection of cutaways is << 337 // just keep cutting. Unions are more trick << 338 // multiple passes and this is handled in << 339 // G4OpenGLImmediate/StoredViewer::ProcessVi << 340 const G4Planes& cutaways = fVP.GetCutawayPla << 341 size_t nPlanes = cutaways.size(); << 342 if (fVP.IsCutaway() && << 343 fVP.GetCutawayMode() == G4ViewParameters << 344 double a[4]; << 345 a[0] = cutaways[0].a(); << 346 a[1] = cutaways[0].b(); << 347 a[2] = cutaways[0].c(); << 348 a[3] = cutaways[0].d(); << 349 glClipPlane (GL_CLIP_PLANE2, a); << 350 glEnable (GL_CLIP_PLANE2); << 351 if (nPlanes > 1) { << 352 a[0] = cutaways[1].a(); << 353 a[1] = cutaways[1].b(); << 354 a[2] = cutaways[1].c(); << 355 a[3] = cutaways[1].d(); << 356 glClipPlane (GL_CLIP_PLANE3, a); << 357 glEnable (GL_CLIP_PLANE3); << 358 } << 359 if (nPlanes > 2) { << 360 a[0] = cutaways[2].a(); << 361 a[1] = cutaways[2].b(); << 362 a[2] = cutaways[2].c(); << 363 a[3] = cutaways[2].d(); << 364 glClipPlane (GL_CLIP_PLANE4, a); << 365 glEnable (GL_CLIP_PLANE4); << 366 } << 367 } else { << 368 glDisable (GL_CLIP_PLANE2); << 369 glDisable (GL_CLIP_PLANE3); << 370 glDisable (GL_CLIP_PLANE4); << 371 } 170 } 372 << 171 else { 373 // Background. << 172 glDisable (GL_CLIP_PLANE0); 374 background = fVP.GetBackgroundColour (); << 173 glDisable (GL_CLIP_PLANE1); 375 << 174 } 376 } << 175 377 << 378 << 379 << 380 void G4OpenGLViewer::ResetView () { << 381 G4VViewer::ResetView(); << 382 fRot_sens = 1; << 383 fPan_sens = 0.01; << 384 } 176 } 385 177 386 << 387 void G4OpenGLViewer::HaloingFirstPass () { 178 void G4OpenGLViewer::HaloingFirstPass () { 388 179 389 //To perform haloing, first Draw all informa 180 //To perform haloing, first Draw all information to the depth buffer 390 //alone, using a chunky line width, and then 181 //alone, using a chunky line width, and then Draw all info again, to 391 //the colour buffer, setting a thinner line 182 //the colour buffer, setting a thinner line width an the depth testing 392 //function to less than or equal, so if two 183 //function to less than or equal, so if two lines cross, the one 393 //passing behind the other will not pass the 184 //passing behind the other will not pass the depth test, and so not 394 //get rendered either side of the infront li 185 //get rendered either side of the infront line for a short distance. 395 186 396 //First, disable writing to the colo(u)r buf 187 //First, disable writing to the colo(u)r buffer... 397 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, G 188 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 398 189 399 //Now enable writing to the depth buffer... 190 //Now enable writing to the depth buffer... 400 glDepthMask (GL_TRUE); 191 glDepthMask (GL_TRUE); 401 glDepthFunc (GL_LESS); 192 glDepthFunc (GL_LESS); 402 glClearDepth (1.0); 193 glClearDepth (1.0); 403 194 404 //Finally, set the line width to something w 195 //Finally, set the line width to something wide... 405 ChangeLineWidth(3.0); << 196 glLineWidth (3.0); 406 197 407 } 198 } 408 199 409 void G4OpenGLViewer::HaloingSecondPass () { 200 void G4OpenGLViewer::HaloingSecondPass () { 410 201 411 //And finally, turn the colour buffer back o 202 //And finally, turn the colour buffer back on with a sesible line width... 412 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_T 203 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 413 glDepthFunc (GL_LEQUAL); 204 glDepthFunc (GL_LEQUAL); 414 ChangeLineWidth(1.0); << 205 glLineWidth (1.0); 415 206 416 } 207 } 417 208 418 G4String G4OpenGLViewer::Pick(GLdouble x, GLdo << 209 void G4OpenGLViewer::HLRFirstPass () { 419 { << 420 const std::vector < G4OpenGLViewerPickMap* > << 421 G4String txt = ""; << 422 if (pickMap.size() == 0) { << 423 // txt += "No hits recorded.";; << 424 } else { << 425 for (unsigned int a=0; a < pickMap.size(); << 426 if (pickMap[a]->getAttributes().size() > << 427 txt += pickMap[a]->print(); << 428 } << 429 } << 430 } << 431 return txt; << 432 } << 433 210 434 const std::vector < G4OpenGLViewerPickMap* > & << 211 G4cout << "First pass HLR" << G4endl; 435 { << 436 static std::vector < G4OpenGLViewerPickMap* << 437 for (auto pickMap: pickMapVector) { << 438 delete pickMap; << 439 } << 440 pickMapVector.clear(); << 441 << 442 const G4int BUFSIZE = 512; << 443 GLuint selectBuffer[BUFSIZE]; << 444 glSelectBuffer(BUFSIZE, selectBuffer); << 445 glRenderMode(GL_SELECT); << 446 glInitNames(); << 447 glPushName(0); << 448 glMatrixMode(GL_PROJECTION); << 449 G4double currentProjectionMatrix[16]; << 450 glGetDoublev(GL_PROJECTION_MATRIX, currentPr << 451 glPushMatrix(); << 452 glLoadIdentity(); << 453 GLint viewport[4]; << 454 glGetIntegerv(GL_VIEWPORT, viewport); << 455 /* G4cout << 456 << "viewport, x,y: " << 457 << viewport[0] << ',' << viewport[1] << ',' << 458 << ", " << x << ',' << y << 459 << G4endl; << 460 */ << 461 fIsGettingPickInfos = true; << 462 // Define 5x5 pixel pick area << 463 g4GluPickMatrix(x, viewport[3] - y, 5., 5., << 464 glMultMatrixd(currentProjectionMatrix); << 465 glMatrixMode(GL_MODELVIEW); << 466 DrawView(); << 467 GLint hits = glRenderMode(GL_RENDER); << 468 fIsGettingPickInfos = false; << 469 if (hits < 0) { << 470 G4cout << "Too many hits. Zoom in to redu << 471 goto restoreMatrices; << 472 } << 473 if (hits > 0) { << 474 GLuint* p = selectBuffer; << 475 for (GLint i = 0; i < hits; ++i) { << 476 GLuint nnames = *p++; << 477 // This bit of debug code or... << 478 //GLuint zmin = *p++; << 479 //GLuint zmax = *p++; << 480 //G4cout << "Hit " << i << ": " << nname << 481 // << "\nzmin: " << zmin << ", zma << 482 // ...just increment the pointer << 483 p++; << 484 p++; << 485 for (GLuint j = 0; j < nnames; ++j) { << 486 GLuint name = *p++; << 487 std::map<GLuint, G4AttHolder*>::iterator ite << 488 fOpenGLSceneHandler.fPickMap.find(name); << 489 if (iter != fOpenGLSceneHandler.fPickMap.end << 490 G4AttHolder* attHolder = iter->second; << 491 if(attHolder && attHolder->GetAttDefs().si << 492 for (size_t iAtt = 0; << 493 iAtt < attHolder->GetAttDefs().size(); ++ << 494 std::ostringstream oss; << 495 oss << G4AttCheck(attHolder->GetAttVal << 496 attHolder->Get << 497 G4OpenGLViewerPickMap* pickMap = << 498 // G4cout << 499 // << "i,j, attHolder->GetAttDefs << 500 // << i << ',' << j << 501 // << ", " << attHolder->GetAttDe << 502 // << G4endl; << 503 // G4cout << "G4OpenGLViewer::Get << 504 pickMap->addAttributes(oss.str() << 505 pickMap->setHitNumber(i); << 506 pickMap->setSubHitNumber(j); << 507 pickMap->setPickName(name); << 508 pickMapVector.push_back(pickMap) << 509 } << 510 } << 511 } << 512 } << 513 } << 514 } << 515 << 516 restoreMatrices: << 517 glMatrixMode(GL_PROJECTION); << 518 glPopMatrix(); << 519 glMatrixMode(GL_MODELVIEW); << 520 << 521 return pickMapVector; << 522 } << 523 << 524 GLubyte* G4OpenGLViewer::grabPixels << 525 (int inColor, unsigned int width, unsigned int << 526 << 527 GLubyte* buffer; << 528 GLint swapbytes, lsbfirst, rowlength; << 529 GLint skiprows, skippixels, alignment; << 530 GLenum format; << 531 int size; << 532 << 533 if (inColor) { << 534 format = GL_RGB; << 535 size = width*height*3; << 536 } else { << 537 format = GL_LUMINANCE; << 538 size = width*height*1; << 539 } << 540 << 541 buffer = new GLubyte[size]; << 542 if (buffer == NULL) << 543 return NULL; << 544 << 545 glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapby << 546 glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirs << 547 glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlen << 548 << 549 glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprow << 550 glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skipp << 551 glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignme << 552 << 553 glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALS << 554 glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE << 555 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); << 556 << 557 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); << 558 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); << 559 glPixelStorei (GL_UNPACK_ALIGNMENT, 1); << 560 << 561 glReadBuffer(GL_FRONT); << 562 glReadPixels (0, 0, (GLsizei)width, (GLsizei << 563 << 564 glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbyt << 565 glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst << 566 glPixelStorei (GL_UNPACK_ROW_LENGTH, rowleng << 567 << 568 glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows << 569 glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippi << 570 glPixelStorei (GL_UNPACK_ALIGNMENT, alignmen << 571 << 572 return buffer; << 573 } << 574 << 575 bool G4OpenGLViewer::printVectoredEPS() { << 576 return printGl2PS(); << 577 } << 578 << 579 bool G4OpenGLViewer::printNonVectoredEPS () { << 580 << 581 int width = getRealExportWidth(); << 582 int height = getRealExportHeight(); << 583 << 584 FILE* fp; << 585 GLubyte* pixels; << 586 GLubyte* curpix; << 587 int components, pos, i; << 588 << 589 pixels = grabPixels (fPrintColour, width, he << 590 << 591 if (pixels == NULL) { << 592 G4cerr << "Failed to get pixels from Ope << 593 return false; << 594 } << 595 if (fPrintColour) { << 596 components = 3; << 597 } else { << 598 components = 1; << 599 } << 600 std::string name = getRealPrintFilename(); << 601 fp = fopen (name.c_str(), "w"); << 602 if (fp == NULL) { << 603 G4cerr << "Can't open filename " << name.c << 604 return false; << 605 } << 606 << 607 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n"); << 608 fprintf (fp, "%%%%Title: %s\n", name.c_str() << 609 fprintf (fp, "%%%%Creator: OpenGL pixmap ren << 610 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", << 611 fprintf (fp, "%%%%EndComments\n"); << 612 fprintf (fp, "gsave\n"); << 613 fprintf (fp, "/bwproc {\n"); << 614 fprintf (fp, " rgbproc\n"); << 615 fprintf (fp, " dup length 3 idiv string 0 << 616 fprintf (fp, " 5 -1 roll {\n"); << 617 fprintf (fp, " add 2 1 roll 1 sub dup 0 e << 618 fprintf (fp, " { pop 3 idiv 3 -1 roll dup << 619 fprintf (fp, " 3 1 roll 5 -1 roll } pu << 620 fprintf (fp, " { 2 1 roll } ifelse\n"); << 621 fprintf (fp, " }forall\n"); << 622 fprintf (fp, " pop pop pop\n"); << 623 fprintf (fp, "} def\n"); << 624 fprintf (fp, "systemdict /colorimage known n << 625 fprintf (fp, " /colorimage {\n"); << 626 fprintf (fp, " pop\n"); << 627 fprintf (fp, " pop\n"); << 628 fprintf (fp, " /rgbproc exch def\n"); << 629 fprintf (fp, " { bwproc } image\n"); << 630 fprintf (fp, " } def\n"); << 631 fprintf (fp, "} if\n"); << 632 fprintf (fp, "/picstr %d string def\n", widt << 633 fprintf (fp, "%d %d scale\n", width, height) << 634 fprintf (fp, "%d %d %d\n", width, height, 8) << 635 fprintf (fp, "[%d 0 0 %d 0 0]\n", width, hei << 636 fprintf (fp, "{currentfile picstr readhexstr << 637 fprintf (fp, "false %d\n", components); << 638 fprintf (fp, "colorimage\n"); << 639 << 640 curpix = (GLubyte*) pixels; << 641 pos = 0; << 642 for (i = width*height*components; i>0; i--) << 643 fprintf (fp, "%02hx ", (unsigned short)(*( << 644 if (++pos >= 32) { << 645 fprintf (fp, "\n"); << 646 pos = 0; << 647 } << 648 } << 649 if (pos) << 650 fprintf (fp, "\n"); << 651 << 652 fprintf (fp, "grestore\n"); << 653 fprintf (fp, "showpage\n"); << 654 delete [] pixels; << 655 fclose (fp); << 656 << 657 // Reset for next time (useful if size chang << 658 // fPrintSizeX = -1; << 659 // fPrintSizeY = -1; << 660 << 661 return true; << 662 } << 663 << 664 /** Return if gl2ps is currently writing << 665 */ << 666 bool G4OpenGLViewer::isGl2psWriting() { << 667 << 668 if (!fGL2PSAction) return false; << 669 if (fGL2PSAction->fileWritingEnabled()) { << 670 return true; << 671 } << 672 return false; << 673 } << 674 << 675 << 676 G4bool G4OpenGLViewer::isFramebufferReady() { << 677 bool check = false; << 678 #ifdef G4VIS_BUILD_OPENGLQT_DRIVER << 679 check = true; << 680 #endif << 681 #ifdef G4VIS_BUILD_OPENGLX_DRIVER << 682 check = false; << 683 #endif << 684 #ifdef G4VIS_BUILD_OPENGLXM_DRIVER << 685 check = false; << 686 #endif << 687 #ifdef G4VIS_BUILD_OPENGLWIN32_DRIVER << 688 check = false; << 689 #endif << 690 << 691 #if GL_ARB_framebuffer_object << 692 if (check) { << 693 // if ( glCheckFramebufferStatus(GL_FRAMEBU << 694 // return false; << 695 // } << 696 } << 697 #endif << 698 return true; << 699 } << 700 << 701 << 702 /* Draw Gl2Ps text if needed << 703 */ << 704 void G4OpenGLViewer::DrawText(const G4Text& g4 << 705 { << 706 // gl2ps or GL window ? << 707 if (isGl2psWriting()) { << 708 << 709 G4VSceneHandler::MarkerSizeType sizeType; << 710 G4double size = fSceneHandler.GetMarkerSiz << 711 G4Point3D position = g4text.GetPosition(); << 712 << 713 G4String textString = g4text.GetText(); << 714 << 715 glRasterPos3d(position.x(),position.y(),po << 716 GLint align = GL2PS_TEXT_B; << 717 << 718 switch (g4text.GetLayout()) { << 719 case G4Text::left: align = GL2PS_TEXT_BL; << 720 case G4Text::centre: align = GL2PS_TEXT_B; << 721 case G4Text::right: align = GL2PS_TEXT_BR; << 722 } << 723 << 724 fGL2PSAction->addTextOpt(textString.c_str( << 725 << 726 } else { << 727 << 728 static G4int callCount = 0; << 729 ++callCount; << 730 //if (callCount <= 10 || callCount%100 == << 731 if (callCount <= 1) { << 732 G4cout << << 733 "G4OpenGLViewer::DrawText: Not implemented f << 734 << fName << << 735 "\"\n Called with " << 736 << g4text << 737 << G4endl; << 738 } << 739 } << 740 } << 741 << 742 /** Change PointSize on gl2ps if needed << 743 */ << 744 void G4OpenGLViewer::ChangePointSize(G4double << 745 << 746 if (isGl2psWriting()) { << 747 fGL2PSAction->setPointSize(int(size)); << 748 } else { << 749 glPointSize (size); << 750 } << 751 } << 752 << 753 << 754 /** Change LineSize on gl2ps if needed << 755 */ << 756 void G4OpenGLViewer::ChangeLineWidth(G4double << 757 << 758 if (isGl2psWriting()) { << 759 fGL2PSAction->setLineWidth(int(width)); << 760 } else { << 761 glLineWidth (width); << 762 } << 763 } << 764 << 765 /** << 766 Export image with the given name with width a << 767 Several cases : << 768 If name is "", filename will have the default << 769 If name is "toto.png", set the name to "toto" << 770 If name is "toto", set the name to "toto" and << 771 Will also add an incremented suffix at the << 772 */ << 773 bool G4OpenGLViewer::exportImage(std::string n << 774 << 775 if (! setExportFilename(name)) { << 776 return false; << 777 } << 778 << 779 if ((width != -1) && (height != -1)) { << 780 setExportSize(width, height); << 781 } << 782 << 783 if (fExportImageFormat == "eps") { << 784 fGL2PSAction->setExportImageFormat_EPS(); << 785 } else if (fExportImageFormat == "ps") { << 786 fGL2PSAction->setExportImageFormat_PS(); << 787 } else if (fExportImageFormat == "svg") { << 788 fGL2PSAction->setExportImageFormat_SVG(); << 789 } else if (fExportImageFormat == "pdf") { << 790 fGL2PSAction->setExportImageFormat_PDF(); << 791 } else { << 792 setExportImageFormat(fExportImageFormat,tr << 793 return false; << 794 } << 795 << 796 bool res; << 797 << 798 // Change the LC_NUMERIC value in order to h << 799 // This case is only useful for French, Cana << 800 size_t len = strlen(setlocale(LC_NUMERIC,NUL << 801 char* oldLocale = (char*)(malloc(len+1)); << 802 if(oldLocale!=NULL) strncpy(oldLocale,setloc << 803 setlocale(LC_NUMERIC,"C"); << 804 << 805 if (((fExportImageFormat == "eps") || (fExpo << 806 res = printNonVectoredEPS(); << 807 } else { << 808 res = printVectoredEPS(); << 809 } << 810 << 811 // restore the local << 812 if (oldLocale) { << 813 setlocale(LC_NUMERIC,oldLocale); << 814 free(oldLocale); << 815 } << 816 << 817 if (res == false) { << 818 G4cerr << "Error saving file... " << getRe << 819 } else { << 820 G4cout << "File " << getRealPrintFilename( << 821 << 822 // increment index if necessary << 823 if ( fExportFilenameIndex != -1) { << 824 fExportFilenameIndex++; << 825 } << 826 } << 827 << 828 return res; << 829 } << 830 212 >> 213 //Hidden line drawing requires three renderings to different buffers, so it >> 214 //cannot be treated in G4OpenGLSceneHandler alone (as can wireframe or hidden >> 215 //surface (solid) mode) 831 216 832 bool G4OpenGLViewer::printGl2PS() { << 217 //So, after SIGGRAPH97 833 218 834 int width = getRealExportWidth(); << 219 //1) Disable the colour and depth buffers, and Draw polygons in wireframe 835 int height = getRealExportHeight(); << 220 // mode to the stencil buffer, setting stencil value to 1 where pixels go. 836 bool res = true; << 837 << 838 // no need to redraw at each new primitive f << 839 G4OpenGLSceneHandler& oglSceneHandler = dyna << 840 G4OpenGLSceneHandler::FlushAction originalFl << 841 oglSceneHandler.SetFlushAction(G4OpenGLScene << 842 << 843 if (!fGL2PSAction) return false; << 844 << 845 fGL2PSAction->setFileName(getRealPrintFilena << 846 // try to resize << 847 int X = fWinSize_x; << 848 int Y = fWinSize_y; << 849 << 850 fWinSize_x = width; << 851 fWinSize_y = height; << 852 // Laurent G. 16/03/10 : Not the good way to << 853 // We should draw in a new offscreen context << 854 // resizing and drawing in current window... << 855 // This should be solve when we will do an o << 856 // to render OpenGL << 857 // See : << 858 // http://developer.apple.com/Mac/library/do << 859 // http://www.songho.ca/opengl/gl_fbo.html << 860 << 861 ResizeGLView(); << 862 bool extendBuffer = true; << 863 bool endWriteAction = false; << 864 bool beginWriteAction = true; << 865 bool filePointerOk = true; << 866 while ((extendBuffer) && (! endWriteAction) << 867 << 868 beginWriteAction = fGL2PSAction->enableFi << 869 if(beginWriteAction) { << 870 GLint vp[4]; << 871 ::glGetIntegerv(GL_VIEWPORT,vp); << 872 fGL2PSAction->setViewport(vp[0],vp[1],v << 873 beginWriteAction = fGL2PSAction->beginP << 874 } << 875 << 876 // 3 cases : << 877 // - true << 878 // - false && ! fGL2PSAction->fileWriting << 879 // - false && fGL2PSAction->fileWritingEn << 880 << 881 filePointerOk = fGL2PSAction->fileWriting << 882 << 883 if (beginWriteAction) { << 884 << 885 // Set the viewport << 886 // By default, we choose the line width << 887 fGL2PSAction->setLineWidth(fGl2psDefaul << 888 // By default, we choose the point size << 889 fGL2PSAction->setPointSize(fGl2psDefaul << 890 << 891 DrawView (); << 892 << 893 endWriteAction = fGL2PSAction->endPage( << 894 fGL2PSAction->disableFileWriting(); << 895 } << 896 if (filePointerOk) { << 897 if ((! endWriteAction) || (! beginWrite << 898 extendBuffer = fGL2PSAction->extendBu << 899 } << 900 } << 901 } << 902 fGL2PSAction->resetBufferSizeParameters(); << 903 << 904 if (!extendBuffer ) { << 905 G4cerr << "ERROR: gl2ps buffer size is no << 906 res = false; << 907 } << 908 if (!beginWriteAction ) { << 909 G4cerr << "ERROR: saving file "<<getRealP << 910 res = false; << 911 } << 912 if (!endWriteAction ) { << 913 G4cerr << "gl2ps error. No output produce << 914 res = false; << 915 } << 916 fWinSize_x = X; << 917 fWinSize_y = Y; << 918 << 919 oglSceneHandler.SetFlushAction(originalFlush << 920 << 921 // Reset for next time (useful is size chang << 922 // fPrintSizeX = 0; << 923 // fPrintSizeY = 0; << 924 221 925 return res; << 222 //First, disable writing to the colo(u)r buffer... 926 } << 223 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 927 << 928 unsigned int G4OpenGLViewer::getWinWidth() con << 929 return fWinSize_x; << 930 } << 931 << 932 unsigned int G4OpenGLViewer::getWinHeight() co << 933 return fWinSize_y; << 934 } << 935 << 936 G4bool G4OpenGLViewer::sizeHasChanged() { << 937 return fSizeHasChanged; << 938 } << 939 << 940 G4int G4OpenGLViewer::getRealExportWidth() { << 941 if (fPrintSizeX == -1) { << 942 return fWinSize_x; << 943 } << 944 GLint dims[2]; << 945 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); << 946 << 947 // L.Garnier 01-2010: Some problems with mac << 948 if ((dims[0] !=0 ) && (dims[1] !=0)) { << 949 if (fPrintSizeX > dims[0]){ << 950 return dims[0]; << 951 } << 952 } << 953 if (fPrintSizeX < -1){ << 954 return 0; << 955 } << 956 return fPrintSizeX; << 957 } << 958 << 959 G4int G4OpenGLViewer::getRealExportHeight() { << 960 if (fPrintSizeY == -1) { << 961 return fWinSize_y; << 962 } << 963 GLint dims[2]; << 964 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); << 965 << 966 // L.Garnier 01-2010: Some problems with mac << 967 if ((dims[0] !=0 ) && (dims[1] !=0)) { << 968 if (fPrintSizeY > dims[1]){ << 969 return dims[1]; << 970 } << 971 } << 972 if (fPrintSizeY < -1){ << 973 return 0; << 974 } << 975 return fPrintSizeY; << 976 } << 977 << 978 void G4OpenGLViewer::setExportSize(G4int X, G4 << 979 fPrintSizeX = X; << 980 fPrintSizeY = Y; << 981 } << 982 << 983 /** << 984 If name is "" or "!", filename and extension << 985 If name is "toto.png", set the name to "toto" << 986 If name is "toto", set the name to "toto" and << 987 If name is the same as previous, do not reset << 988 */ << 989 bool G4OpenGLViewer::setExportFilename(G4Strin << 990 if (name == "!") { << 991 name = ""; << 992 } << 993 << 994 if (inc) { << 995 if ((name != "") && (fExportFilename != na << 996 fExportFilenameIndex=0; << 997 } << 998 } else { << 999 fExportFilenameIndex=-1; << 1000 } << 1001 << 1002 if (name.size() == 0) { << 1003 name = getRealPrintFilename().c_str(); << 1004 } else { << 1005 // guess format by extention << 1006 std::string extension = name.substr(name. << 1007 // If there is a dot in the name the abov << 1008 if (extension.size() >= 3 && extension.si << 1009 if (setExportImageFormat(extension, fal << 1010 fExportFilename = name.substr(0,name. << 1011 } else { // No viable extension found << 1012 return false; << 1013 } << 1014 } else { // Assume name is already the r << 1015 fExportFilename = name; << 1016 } << 1017 } << 1018 return true; << 1019 } << 1020 224 1021 std::string G4OpenGLViewer::getRealPrintFilen << 225 //Enable the stencil buffer... 1022 std::string temp = fExportFilename; << 226 glEnable (GL_STENCIL_TEST); 1023 if (fExportFilenameIndex != -1) { << 1024 temp += std::string("_"); << 1025 std::ostringstream os; << 1026 os << std::setw(4) << std::setfill('0') < << 1027 std::string nb_str = os.str(); << 1028 temp += nb_str; << 1029 } << 1030 temp += "."+fExportImageFormat; << 1031 return temp; << 1032 } << 1033 227 1034 GLdouble G4OpenGLViewer::getSceneNearWidth() << 228 //Now disable writing to the depth buffer... 1035 { << 229 glDisable (GL_DEPTH_TEST); 1036 if (!fSceneHandler.GetScene()) { << 1037 return 0; << 1038 } << 1039 const G4Point3D targetPoint << 1040 = fSceneHandler.GetScene()->GetStandardTa << 1041 + fVP.GetCurrentTargetPoint (); << 1042 G4double radius = fSceneHandler.GetScene()- << 1043 if(radius<=0.) radius = 1.; << 1044 const G4double cameraDistance = fVP.GetCame << 1045 const GLdouble pnear = fVP.GetNearDistanc << 1046 return 2 * fVP.GetFrontHalfHeight (pnear, r << 1047 } << 1048 230 1049 GLdouble G4OpenGLViewer::getSceneFarWidth() << 231 //Clear all stencil buffer values to 0... 1050 { << 232 glClearStencil (0); 1051 if (!fSceneHandler.GetScene()) { << 233 glClear (GL_STENCIL_BUFFER_BIT); 1052 return 0; << 1053 } << 1054 const G4Point3D targetPoint << 1055 = fSceneHandler.GetScene()->GetStandardTa << 1056 + fVP.GetCurrentTargetPoint (); << 1057 G4double radius = fSceneHandler.GetScene()- << 1058 if(radius<=0.) radius = 1.; << 1059 const G4double cameraDistance = fVP.GetCame << 1060 const GLdouble pnear = fVP.GetNearDistanc << 1061 const GLdouble pfar = fVP.GetFarDistance << 1062 return 2 * fVP.GetFrontHalfHeight (pfar, ra << 1063 } << 1064 234 >> 235 //Prepare stencil buffer... >> 236 glStencilFunc (GL_ALWAYS, //When to pass a pixel in the stencil test >> 237 0x1, //The ref val to compare with masked stencil val >> 238 0x1); //The mask to AND with ref and val before test 1065 239 1066 GLdouble G4OpenGLViewer::getSceneDepth() << 240 glStencilOp (GL_KEEP, //If stencil test fails *irrelevant* 1067 { << 241 GL_KEEP, //If depth test passes *irrelevant* 1068 if (!fSceneHandler.GetScene()) { << 242 GL_REPLACE); //If no depth test *this is applied to every pixel 1069 return 0; << 243 //drawn to the stencil buffer in this pass* 1070 } << 1071 const G4Point3D targetPoint << 1072 = fSceneHandler.GetScene()->GetStandardTa << 1073 + fVP.GetCurrentTargetPoint (); << 1074 G4double radius = fSceneHandler.GetScene()- << 1075 if(radius<=0.) radius = 1.; << 1076 const G4double cameraDistance = fVP.GetCame << 1077 const GLdouble pnear = fVP.GetNearDistanc << 1078 return fVP.GetFarDistance (cameraDistance, << 1079 } << 1080 244 >> 245 //Hence, everywhere a pixel is drawn, stencil value=1, 0 everywhere else. 1081 246 >> 247 //Set the drawing style to wireframe... >> 248 fVP.SetDrawingStyle (G4ViewParameters::wireframe); 1082 249 1083 void G4OpenGLViewer::rotateScene(G4double dx, << 250 NeedKernelVisit (); 1084 { << 251 ProcessView (); 1085 if (fVP.GetRotationStyle() == G4ViewParamet << 1086 rotateSceneInViewDirection(dx,dy); << 1087 } else { << 1088 if( dx != 0) { << 1089 rotateSceneThetaPhi(dx,0); << 1090 } << 1091 if( dy != 0) { << 1092 rotateSceneThetaPhi(0,dy); << 1093 } << 1094 } << 1095 } 252 } 1096 253 >> 254 void G4OpenGLViewer::HLRSecondPass () { 1097 255 1098 void G4OpenGLViewer::rotateSceneToggle(G4doub << 256 G4cout << "Second pass HLR" << G4endl; 1099 { << 1100 if (fVP.GetRotationStyle() != G4ViewParamet << 1101 rotateSceneInViewDirection(dx,dy); << 1102 } else { << 1103 if( dx != 0) { << 1104 rotateSceneThetaPhi(dx,0); << 1105 } << 1106 if( dy != 0) { << 1107 rotateSceneThetaPhi(0,dy); << 1108 } << 1109 } << 1110 } << 1111 257 1112 void G4OpenGLViewer::rotateSceneThetaPhi(G4do << 258 //2) Use the stencil buffer to mask out pixels where stencil value = 1, and 1113 { << 259 // render to the stencil buffer as depth tested filled polygons. 1114 if (!fSceneHandler.GetScene()) { << 1115 return; << 1116 } << 1117 260 1118 G4Vector3D vp; << 261 glStencilFunc (GL_EQUAL, 0x1, 0x1); 1119 G4Vector3D up; << 262 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); 1120 << 263 glDepthFunc (GL_LEQUAL); 1121 G4Vector3D xprime; << 264 glEnable (GL_DEPTH_TEST); 1122 G4Vector3D yprime; << 1123 G4Vector3D zprime; << 1124 << 1125 G4double delta_alpha; << 1126 G4double delta_theta; << 1127 << 1128 G4Vector3D new_vp; << 1129 G4Vector3D new_up; << 1130 << 1131 G4double cosalpha; << 1132 G4double sinalpha; << 1133 << 1134 G4Vector3D a1; << 1135 G4Vector3D a2; << 1136 G4Vector3D delta; << 1137 G4Vector3D viewPoint; << 1138 265 1139 << 266 //Set the drawing style to hlhsr (solid)... 1140 //phi spin stuff here << 267 fVP.SetDrawingStyle (G4ViewParameters::hsr); 1141 << 1142 vp = fVP.GetViewpointDirection ().unit (); << 1143 up = fVP.GetUpVector ().unit (); << 1144 << 1145 yprime = (up.cross(vp)).unit(); << 1146 zprime = (vp.cross(yprime)).unit(); << 1147 << 1148 if (fVP.GetLightsMoveWithCamera()) { << 1149 delta_alpha = dy * fRot_sens; << 1150 delta_theta = -dx * fRot_sens; << 1151 } else { << 1152 delta_alpha = -dy * fRot_sens; << 1153 delta_theta = dx * fRot_sens; << 1154 } << 1155 << 1156 delta_alpha *= CLHEP::deg; << 1157 delta_theta *= CLHEP::deg; << 1158 268 1159 new_vp = std::cos(delta_alpha) * vp + std:: << 269 NeedKernelVisit (); 1160 << 270 ProcessView (); 1161 // to avoid z rotation flipping << 1162 // to allow more than 360° rotation << 1163 271 1164 if (fVP.GetLightsMoveWithCamera()) { << 1165 new_up = (new_vp.cross(yprime)).unit(); << 1166 if (new_vp.z()*vp.z() <0) { << 1167 new_up.set(new_up.x(),-new_up.y(),new_u << 1168 } << 1169 } else { << 1170 new_up = up; << 1171 if (new_vp.z()*vp.z() <0) { << 1172 new_up.set(new_up.x(),-new_up.y(),new_u << 1173 } << 1174 } << 1175 fVP.SetUpVector(new_up); << 1176 //////////////// << 1177 // Rotates by fixed azimuthal angle delta_t << 1178 << 1179 cosalpha = new_up.dot (new_vp.unit()); << 1180 sinalpha = std::sqrt (1. - std::pow (cosalp << 1181 yprime = (new_up.cross (new_vp.unit())).uni << 1182 xprime = yprime.cross (new_up); << 1183 // Projection of vp on plane perpendicular << 1184 a1 = sinalpha * xprime; << 1185 // Required new projection... << 1186 a2 = sinalpha * (std::cos (delta_theta) * x << 1187 // Required Increment vector... << 1188 delta = a2 - a1; << 1189 // So new viewpoint is... << 1190 viewPoint = new_vp.unit() + delta; << 1191 << 1192 fVP.SetViewAndLights (viewPoint); << 1193 } 272 } 1194 273 1195 << 274 void G4OpenGLViewer::HLRThirdPass () { 1196 void G4OpenGLViewer::rotateSceneInViewDirecti << 1197 { << 1198 if (!fSceneHandler.GetScene()) { << 1199 return; << 1200 } << 1201 << 1202 G4Vector3D vp; << 1203 G4Vector3D up; << 1204 275 1205 G4Vector3D xprime; << 276 //3) Turn off the stencil buffer, turn on the colour buffer 1206 G4Vector3D yprime; << 277 // and render polygons in wireframe mode. 1207 G4Vector3D zprime; << 1208 << 1209 G4Vector3D new_vp; << 1210 G4Vector3D new_up; << 1211 << 1212 G4Vector3D a1; << 1213 G4Vector3D a2; << 1214 G4Vector3D delta; << 1215 G4Vector3D viewPoint; << 1216 << 1217 dx = dx/100; << 1218 dy = dy/100; << 1219 << 1220 //phi spin stuff here << 1221 << 1222 vp = fVP.GetViewpointDirection ().unit(); << 1223 up = fVP.GetUpVector ().unit(); << 1224 << 1225 G4Vector3D zPrimeVector = G4Vector3D(up.y() << 1226 up.z()*vp.x()-up << 1227 up.x()*vp.y()-up << 1228 << 1229 viewPoint = vp/fRot_sens + (zPrimeVector*dx << 1230 new_up = G4Vector3D(viewPoint.y()*zPrimeVec << 1231 viewPoint.z()*zPrimeVe << 1232 viewPoint.x()*zPrimeVe << 1233 << 1234 G4Vector3D new_upUnit = new_up.unit(); << 1235 << 1236 << 1237 << 1238 fVP.SetUpVector(new_upUnit); << 1239 fVP.SetViewAndLights (viewPoint); << 1240 } << 1241 << 1242 << 1243 void G4OpenGLViewer::addExportImageFormat(std << 1244 fExportImageFormatVector.push_back(format); << 1245 } << 1246 << 1247 bool G4OpenGLViewer::setExportImageFormat(std << 1248 bool found = false; << 1249 std::string list; << 1250 for (unsigned int a=0; a<fExportImageFormat << 1251 list +=fExportImageFormatVector.at(a) + " << 1252 << 1253 if (fExportImageFormatVector.at(a) == for << 1254 if (! quiet) { << 1255 G4cout << " Changing export format to << 1256 } << 1257 if (format != fExportImageFormat) { << 1258 fExportFilenameIndex = 0; << 1259 fExportImageFormat = format; << 1260 } << 1261 return true; << 1262 } << 1263 } << 1264 if (! found) { << 1265 if (format.size() == 0) { << 1266 G4cout << " Current formats availables << 1267 } else { << 1268 G4cerr << " Format \"" << format << "\" << 1269 } << 1270 } << 1271 return false; << 1272 } << 1273 << 1274 << 1275 // From MESA implementation : << 1276 // http://www.techques.com/question/1-8660454 << 1277 << 1278 void G4OpenGLViewer::g4GluPickMatrix(GLdouble << 1279 GLint viewport[4]) << 1280 { << 1281 GLdouble mat[16]; << 1282 GLdouble sx, sy; << 1283 GLdouble tx, ty; << 1284 << 1285 sx = viewport[2] / width; << 1286 sy = viewport[3] / height; << 1287 tx = (viewport[2] + 2.0 * (viewport[0] - << 1288 ty = (viewport[3] + 2.0 * (viewport[1] - << 1289 << 1290 #define M(row, col) mat[col*4+row] << 1291 M(0, 0) = sx; << 1292 M(0, 1) = 0.0; << 1293 M(0, 2) = 0.0; << 1294 M(0, 3) = tx; << 1295 M(1, 0) = 0.0; << 1296 M(1, 1) = sy; << 1297 M(1, 2) = 0.0; << 1298 M(1, 3) = ty; << 1299 M(2, 0) = 0.0; << 1300 M(2, 1) = 0.0; << 1301 M(2, 2) = 1.0; << 1302 M(2, 3) = 0.0; << 1303 M(3, 0) = 0.0; << 1304 M(3, 1) = 0.0; << 1305 M(3, 2) = 0.0; << 1306 M(3, 3) = 1.0; << 1307 #undef M << 1308 << 1309 glMultMatrixd(mat); << 1310 } << 1311 278 >> 279 G4cout << "Third pass HLR" << G4endl; 1312 280 >> 281 glDisable (GL_STENCIL_TEST); >> 282 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 1313 283 >> 284 //Set the drawing style to hlr wireframe... >> 285 fVP.SetDrawingStyle (G4ViewParameters::wireframe); 1314 286 >> 287 NeedKernelVisit (); >> 288 ProcessView (); 1315 289 1316 // From MESA implementation : << 290 fVP.SetDrawingStyle (G4ViewParameters::hlr); 1317 // https://github.com/jlamarche/iOS-OpenGLES- << 1318 // or http://www.daniweb.com/software-develop << 1319 << 1320 void G4OpenGLViewer::g4GluLookAt( GLdouble ey << 1321 GLdouble centerx, GLd << 1322 centerz, << 1323 GLdouble upx, GLdoubl << 1324 { << 1325 GLdouble mat[16]; << 1326 GLdouble x[3], y[3], z[3]; << 1327 GLdouble mag; << 1328 << 1329 /* Make rotation matrix */ << 1330 << 1331 /* Z vector */ << 1332 z[0] = eyex - centerx; << 1333 z[1] = eyey - centery; << 1334 z[2] = eyez - centerz; << 1335 mag = std::sqrt(z[0] * z[0] + z[1] * z[1] + << 1336 if (mag) { /* mpichler, 19950515 */ << 1337 z[0] /= mag; << 1338 z[1] /= mag; << 1339 z[2] /= mag; << 1340 } << 1341 << 1342 /* Y vector */ << 1343 y[0] = upx; << 1344 y[1] = upy; << 1345 y[2] = upz; << 1346 << 1347 /* X vector = Y cross Z */ << 1348 x[0] = y[1] * z[2] - y[2] * z[1]; << 1349 x[1] = -y[0] * z[2] + y[2] * z[0]; << 1350 x[2] = y[0] * z[1] - y[1] * z[0]; << 1351 << 1352 /* Recompute Y = Z cross X */ << 1353 y[0] = z[1] * x[2] - z[2] * x[1]; << 1354 y[1] = -z[0] * x[2] + z[2] * x[0]; << 1355 y[2] = z[0] * x[1] - z[1] * x[0]; << 1356 << 1357 /* mpichler, 19950515 */ << 1358 /* cross product gives area of parallelogra << 1359 * non-perpendicular unit-length vectors; s << 1360 */ << 1361 << 1362 mag = std::sqrt(x[0] * x[0] + x[1] * x[1] + << 1363 if (mag) { << 1364 x[0] /= mag; << 1365 x[1] /= mag; << 1366 x[2] /= mag; << 1367 } << 1368 << 1369 mag = std::sqrt(y[0] * y[0] + y[1] * y[1] + << 1370 if (mag) { << 1371 y[0] /= mag; << 1372 y[1] /= mag; << 1373 y[2] /= mag; << 1374 } << 1375 << 1376 #define M(row,col) mat[col*4+row] << 1377 M(0, 0) = x[0]; << 1378 M(0, 1) = x[1]; << 1379 M(0, 2) = x[2]; << 1380 M(0, 3) = 0.0; << 1381 M(1, 0) = y[0]; << 1382 M(1, 1) = y[1]; << 1383 M(1, 2) = y[2]; << 1384 M(1, 3) = 0.0; << 1385 M(2, 0) = z[0]; << 1386 M(2, 1) = z[1]; << 1387 M(2, 2) = z[2]; << 1388 M(2, 3) = 0.0; << 1389 M(3, 0) = 0.0; << 1390 M(3, 1) = 0.0; << 1391 M(3, 2) = 0.0; << 1392 M(3, 3) = 1.0; << 1393 #undef M << 1394 glMultMatrixd(mat); << 1395 << 1396 /* Translate Eye to Origin */ << 1397 glTranslated(-eyex, -eyey, -eyez); << 1398 } << 1399 << 1400 void G4OpenGLViewer::g4GlOrtho (GLdouble left << 1401 // glOrtho (left, right, bottom, top, near << 1402 << 1403 GLdouble a = 2.0 / (right - left); << 1404 GLdouble b = 2.0 / (top - bottom); << 1405 GLdouble c = -2.0 / (zFar - zNear); << 1406 << 1407 GLdouble tx = - (right + left)/(right - lef << 1408 GLdouble ty = - (top + bottom)/(top - botto << 1409 GLdouble tz = - (zFar + zNear)/(zFar - zNea << 1410 << 1411 GLdouble ortho[16] = { << 1412 a, 0, 0, 0, << 1413 0, b, 0, 0, << 1414 0, 0, c, 0, << 1415 tx, ty, tz, 1 << 1416 }; << 1417 glMultMatrixd(ortho); << 1418 << 1419 } << 1420 << 1421 << 1422 void G4OpenGLViewer::g4GlFrustum (GLdouble le << 1423 // glFrustum (left, right, bottom, top, ne << 1424 << 1425 GLdouble deltaX = right - left; << 1426 GLdouble deltaY = top - bottom; << 1427 GLdouble deltaZ = zFar - zNear; << 1428 << 1429 GLdouble a = 2.0f * zNear / deltaX; << 1430 GLdouble b = 2.0f * zNear / deltaY; << 1431 GLdouble c = (right + left) / deltaX; << 1432 GLdouble d = (top + bottom) / deltaY; << 1433 GLdouble e = -(zFar + zNear) / (zFar - zNea << 1434 GLdouble f = -2.0f * zFar * zNear / deltaZ; << 1435 << 1436 GLdouble proj[16] = { << 1437 a, 0, 0, 0, << 1438 0, b, 0, 0, << 1439 c, d, e, -1.0f, << 1440 0, 0, f, 0 << 1441 }; << 1442 << 1443 glMultMatrixd(proj); << 1444 << 1445 } 291 } 1446 292 1447 G4String G4OpenGLViewerPickMap::print() { << 293 #endif 1448 std::ostringstream txt; << 1449 for (unsigned int a=0; a<fAttributes.size() << 1450 txt << fAttributes[a]; << 1451 if (a < fAttributes.size() - 1) txt << "\ << 1452 } << 1453 return txt.str(); << 1454 } << 1455 294