Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4OpenGLViewer.cc
이 파일의 문서화 페이지로 가기
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4OpenGLViewer.cc 108131 2018-01-09 13:23:26Z gcosmo $
28 //
29 //
30 // Andrew Walkden 27th March 1996
31 // OpenGL view - opens window, hard copy, etc.
32 
33 #ifdef G4VIS_BUILD_OPENGL_DRIVER
34 
35 #include "G4ios.hh"
36 #include "G4SystemOfUnits.hh"
37 #include "G4OpenGLViewer.hh"
38 #include "G4OpenGLSceneHandler.hh"
39 #include "G4OpenGLTransform3D.hh"
40 #include "G4OpenGL2PSAction.hh"
41 
42 #include "G4Scene.hh"
43 #include "G4VisExtent.hh"
44 #include "G4LogicalVolume.hh"
45 #include "G4VSolid.hh"
46 #include "G4Point3D.hh"
47 #include "G4Normal3D.hh"
48 #include "G4Plane3D.hh"
49 #include "G4AttHolder.hh"
50 #include "G4AttCheck.hh"
51 #include "G4Text.hh"
52 
53 #ifdef G4OPENGL_VERSION_2
54 // We need to have a Wt gl drawer because we will draw inside the WtGL component (ImmediateWtViewer)
55 #include "G4OpenGLVboDrawer.hh"
56 #endif
57 
58 // GL2PS
59 #include "Geant4_gl2ps.h"
60 
61 #include <sstream>
62 #include <string>
63 #include <iomanip>
64 
65 G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
66 G4VViewer (scene, -1),
67 #ifdef G4OPENGL_VERSION_2
68 fVboDrawer(NULL),
69 #endif
70 fPrintColour (true),
71 fVectoredPs (true),
72 fOpenGLSceneHandler(scene),
73 background (G4Colour(0.,0.,0.)),
74 transparency_enabled (true),
75 antialiasing_enabled (false),
76 haloing_enabled (false),
77 fRot_sens(1.),
78 fPan_sens(0.01),
79 fWinSize_x(0),
80 fWinSize_y(0),
81 fDefaultExportImageFormat("pdf"),
82 fExportImageFormat("pdf"),
83 fExportFilenameIndex(0),
84 fPrintSizeX(-1),
85 fPrintSizeY(-1),
86 fPointSize (0),
87 fDefaultExportFilename("G4OpenGL"),
88 fSizeHasChanged(0),
89 fGl2psDefaultLineWith(1),
90 fGl2psDefaultPointSize(2),
91 fGlViewInitialized(false),
92 fIsGettingPickInfos(false)
93 #ifdef G4OPENGL_VERSION_2
94 ,fShaderProgram(0)
95 ,fVertexPositionAttribute(0)
96 ,fVertexNormalAttribute(0)
97 ,fpMatrixUniform(0)
98 ,fcMatrixUniform(0)
99 ,fmvMatrixUniform(0)
100 ,fnMatrixUniform(0)
101 #endif
102 {
103  // Make changes to view parameters for OpenGL...
104  fVP.SetAutoRefresh(true);
105  fDefaultVP.SetAutoRefresh(true);
106 
107  fGL2PSAction = new G4OpenGL2PSAction();
108 
109  // add supported export image format
110  addExportImageFormat("eps");
111  addExportImageFormat("ps");
112  addExportImageFormat("pdf");
113  addExportImageFormat("svg");
114 
115  // Change the default name
116  fExportFilename += fDefaultExportFilename + "_" + GetShortName().data();
117 
118  // glClearColor (0.0, 0.0, 0.0, 0.0);
119  // glClearDepth (1.0);
120  // glDisable (GL_BLEND);
121  // glDisable (GL_LINE_SMOOTH);
122  // glDisable (GL_POLYGON_SMOOTH);
123 
124 }
125 
126 G4OpenGLViewer::~G4OpenGLViewer ()
127 {
128  delete fGL2PSAction;
129 }
130 
131 void G4OpenGLViewer::InitializeGLView ()
132 {
133 #ifdef G4OPENGL_VERSION_2
134  if (fVboDrawer) {
135 
136  // First, load a simple shader
137  fShaderProgram = glCreateProgram();
138  Shader vertexShader = glCreateShader(GL_VERTEX_SHADER);
139  const char * vSrc = fVboDrawer->getVertexShaderSrc();
140  glShaderSource(vertexShader, 1, &vSrc, NULL);
141  glCompileShader(vertexShader);
142  glAttachShader(fShaderProgram, vertexShader);
143 
144  Shader fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
145  const char * fSrc = fVboDrawer->getFragmentShaderSrc();
146  glShaderSource(fragmentShader, 1, &fSrc, NULL);
147  glCompileShader(fragmentShader);
148 
149  glAttachShader(fShaderProgram, fragmentShader);
150  glLinkProgram(fShaderProgram);
151  glUseProgram(fShaderProgram);
152 
153  // UniformLocation uColor = getUniformLocation(fShaderProgram, "uColor");
154  // uniform4fv(uColor, [0.0, 0.3, 0.0, 1.0]);
155 
156  // Extract the references to the attributes from the shader.
157 
158  fVertexPositionAttribute =
159  glGetAttribLocation(fShaderProgram, "aVertexPosition");
160 
161 
162  glEnableVertexAttribArray(fVertexPositionAttribute);
163 
164  // Extract the references the uniforms from the shader
165  fpMatrixUniform = glGetUniformLocation(fShaderProgram, "uPMatrix");
166  fcMatrixUniform = glGetUniformLocation(fShaderProgram, "uCMatrix");
167  fmvMatrixUniform = glGetUniformLocation(fShaderProgram, "uMVMatrix");
168  fnMatrixUniform = glGetUniformLocation(fShaderProgram, "uNMatrix");
169  ftMatrixUniform = glGetUniformLocation(fShaderProgram, "uTMatrix");
170 
171  /* glUniformMatrix4fv(fcMatrixUniform, 1, 0, identity);
172  glUniformMatrix4fv(fpMatrixUniform, 1, 0, identity);
173  glUniformMatrix4fv(ftMatrixUniform, 1, 0, identity);
174  glUniformMatrix4fv(fmvMatrixUniform, 1, 0, identity);
175  */
176  // We have to set that in order to avoid calls on opengl commands before all is ready
177  fGlViewInitialized = true;
178  }
179 #endif
180 
181  if (fWinSize_x == 0) {
182  fWinSize_x = fVP.GetWindowSizeHintX();
183  }
184  if (fWinSize_y == 0) {
185  fWinSize_y = fVP.GetWindowSizeHintY();
186  }
187 
188  glClearColor (0.0, 0.0, 0.0, 0.0);
189  glClearDepth (1.0);
190 #ifndef G4OPENGL_VERSION_2
191  glDisable (GL_LINE_SMOOTH);
192  glDisable (GL_POLYGON_SMOOTH);
193 #endif
194 
195 // clear the buffers and window?
196  ClearView ();
197  FinishView ();
198 
199  glDepthFunc (GL_LEQUAL);
200  glDepthMask (GL_TRUE);
201 
202  glEnable (GL_BLEND);
203  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
204 
205 }
206 
207 void G4OpenGLViewer::ClearView () {
208  ClearViewWithoutFlush();
209 
210  if(!isFramebufferReady()) {
211  return;
212  }
213 
214  glFlush();
215 }
216 
217 
218 void G4OpenGLViewer::ClearViewWithoutFlush () {
219  // Ready for clear ?
220  // See : http://lists.apple.com/archives/mac-opengl/2012/Jul/msg00038.html
221  if(!isFramebufferReady()) {
222  return;
223  }
224 
225  glClearColor (background.GetRed(),
226  background.GetGreen(),
227  background.GetBlue(),
228  1.);
229  glClearDepth (1.0);
230  //Below line does not compile with Mesa includes.
231  //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
232  glClear (GL_COLOR_BUFFER_BIT);
233  glClear (GL_DEPTH_BUFFER_BIT);
234  glClear (GL_STENCIL_BUFFER_BIT);
235 }
236 
237 
238 void G4OpenGLViewer::ResizeWindow(unsigned int aWidth, unsigned int aHeight) {
239  if ((fWinSize_x != aWidth) || (fWinSize_y != aHeight)) {
240  fWinSize_x = aWidth;
241  fWinSize_y = aHeight;
242  fSizeHasChanged = true;
243  } else {
244  fSizeHasChanged = false;
245  }
246 }
247 
254 void G4OpenGLViewer::ResizeGLView()
255 {
256  // Check size
257  GLint dims[2];
258  dims[0] = 0;
259  dims[1] = 0;
260 
261  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
262 
263  if ((dims[0] !=0 ) && (dims[1] !=0)) {
264 
265  if (fWinSize_x > (unsigned)dims[0]) {
266  G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<fWinSize_x <<" is resize to "<< dims[0] << G4endl;
267  fWinSize_x = dims[0];
268  }
269  if (fWinSize_y > (unsigned)dims[1]) {
270  G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<fWinSize_y <<" is resize to "<< dims[1] << G4endl;
271  fWinSize_y = dims[1];
272  }
273  }
274 
275  glViewport(0, 0, fWinSize_x,fWinSize_y);
276 
277 
278 }
279 
280 
281 void G4OpenGLViewer::SetView () {
282  // if getting pick infos, should not resize the view.
283  if (fIsGettingPickInfos) return;
284 
285  if (!fSceneHandler.GetScene()) {
286  return;
287  }
288  // Calculates view representation based on extent of object being
289  // viewed and (initial) viewpoint. (Note: it can change later due
290  // to user interaction via visualization system's GUI.)
291 
292  // Lighting.
293  GLfloat lightPosition [4];
294  lightPosition [0] = fVP.GetActualLightpointDirection().x();
295  lightPosition [1] = fVP.GetActualLightpointDirection().y();
296  lightPosition [2] = fVP.GetActualLightpointDirection().z();
297  lightPosition [3] = 0.;
298  // Light position is "true" light direction, so must come after gluLookAt.
299  GLfloat ambient [] = { 0.2f, 0.2f, 0.2f, 1.f};
300  GLfloat diffuse [] = { 0.8f, 0.8f, 0.8f, 1.f};
301  glEnable (GL_LIGHT0);
302  glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
303  glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
304 
305  G4double ratioX = 1;
306  G4double ratioY = 1;
307  if (fWinSize_y > fWinSize_x) {
308  ratioX = ((G4double)fWinSize_y) / ((G4double)fWinSize_x);
309  }
310  if (fWinSize_x > fWinSize_y) {
311  ratioY = ((G4double)fWinSize_x) / ((G4double)fWinSize_y);
312  }
313 
314  // Get radius of scene, etc.
315  // Note that this procedure properly takes into account zoom, dolly and pan.
316  const G4Point3D targetPoint
317  = fSceneHandler.GetScene()->GetStandardTargetPoint()
318  + fVP.GetCurrentTargetPoint ();
319  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
320  if(radius<=0.) radius = 1.;
321  const G4double cameraDistance = fVP.GetCameraDistance (radius);
322  const G4Point3D cameraPosition =
323  targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
324  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
325  const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
326  const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius) * ratioY;
327  const GLdouble left = -right;
328  const GLdouble top = fVP.GetFrontHalfHeight (pnear, radius) * ratioX;
329  const GLdouble bottom = -top;
330 
331  // FIXME
332  ResizeGLView();
333  //SHOULD SetWindowsSizeHint()...
334 
335  glMatrixMode (GL_PROJECTION); // set up Frustum.
336  glLoadIdentity();
337 
338  const G4Vector3D scaleFactor = fVP.GetScaleFactor();
339  glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
340 
341  if (fVP.GetFieldHalfAngle() == 0.) {
342  g4GlOrtho (left, right, bottom, top, pnear, pfar);
343  }
344  else {
345  g4GlFrustum (left, right, bottom, top, pnear, pfar);
346  }
347 
348  glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
349  glLoadIdentity();
350 
351  const G4Normal3D& upVector = fVP.GetUpVector ();
352  G4Point3D gltarget;
353  if (cameraDistance > 1.e-6 * radius) {
354  gltarget = targetPoint;
355  }
356  else {
357  gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
358  }
359 
360  const G4Point3D& pCamera = cameraPosition; // An alias for brevity.
361 
362  g4GluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
363  gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
364  upVector.x(), upVector.y(), upVector.z()); // Up vector.
365  // Light position is "true" light direction, so must come after gluLookAt.
366  glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
367 
368  // The idea is to use back-to-back clipping planes. This can cut an object
369  // down to just a few pixels, which can make it difficult to see. So, for
370  // now, comment this out and use the generic (Boolean) method, via
371  // G4VSolid* G4OpenGLSceneHandler::CreateSectionSolid ()
372  // { return G4VSceneHandler::CreateSectionSolid(); }
373 // if (fVP.IsSection () ) { // pair of back to back clip planes.
374 // const G4Plane3D& sp = fVP.GetSectionPlane ();
375 // double sArray[4];
376 // sArray[0] = sp.a();
377 // sArray[1] = sp.b();
378 // sArray[2] = sp.c();
379 // sArray[3] = sp.d() + radius * 1.e-05;
380 // glClipPlane (GL_CLIP_PLANE0, sArray);
381 // glEnable (GL_CLIP_PLANE0);
382 // sArray[0] = -sp.a();
383 // sArray[1] = -sp.b();
384 // sArray[2] = -sp.c();
385 // sArray[3] = -sp.d() + radius * 1.e-05;
386 // glClipPlane (GL_CLIP_PLANE1, sArray);
387 // glEnable (GL_CLIP_PLANE1);
388 // } else {
389 // glDisable (GL_CLIP_PLANE0);
390 // glDisable (GL_CLIP_PLANE1);
391 // }
392 
393  // What we call intersection of cutaways is easy in OpenGL. You
394  // just keep cutting. Unions are more tricky - you have to have
395  // multiple passes and this is handled in
396  // G4OpenGLImmediate/StoredViewer::ProcessView.
397  const G4Planes& cutaways = fVP.GetCutawayPlanes();
398  size_t nPlanes = cutaways.size();
399  if (fVP.IsCutaway() &&
400  fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
401  nPlanes > 0) {
402  double a[4];
403  a[0] = cutaways[0].a();
404  a[1] = cutaways[0].b();
405  a[2] = cutaways[0].c();
406  a[3] = cutaways[0].d();
407  glClipPlane (GL_CLIP_PLANE2, a);
408  glEnable (GL_CLIP_PLANE2);
409  if (nPlanes > 1) {
410  a[0] = cutaways[1].a();
411  a[1] = cutaways[1].b();
412  a[2] = cutaways[1].c();
413  a[3] = cutaways[1].d();
414  glClipPlane (GL_CLIP_PLANE3, a);
415  glEnable (GL_CLIP_PLANE3);
416  }
417  if (nPlanes > 2) {
418  a[0] = cutaways[2].a();
419  a[1] = cutaways[2].b();
420  a[2] = cutaways[2].c();
421  a[3] = cutaways[2].d();
422  glClipPlane (GL_CLIP_PLANE4, a);
423  glEnable (GL_CLIP_PLANE4);
424  }
425  } else {
426  glDisable (GL_CLIP_PLANE2);
427  glDisable (GL_CLIP_PLANE3);
428  glDisable (GL_CLIP_PLANE4);
429  }
430 
431  // Background.
432  background = fVP.GetBackgroundColour ();
433 
434 }
435 
436 
437 
438 void G4OpenGLViewer::ResetView () {
440  fRot_sens = 1;
441  fPan_sens = 0.01;
442 }
443 
444 
445 void G4OpenGLViewer::HaloingFirstPass () {
446 
447  //To perform haloing, first Draw all information to the depth buffer
448  //alone, using a chunky line width, and then Draw all info again, to
449  //the colour buffer, setting a thinner line width an the depth testing
450  //function to less than or equal, so if two lines cross, the one
451  //passing behind the other will not pass the depth test, and so not
452  //get rendered either side of the infront line for a short distance.
453 
454  //First, disable writing to the colo(u)r buffer...
455  glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
456 
457  //Now enable writing to the depth buffer...
458  glDepthMask (GL_TRUE);
459  glDepthFunc (GL_LESS);
460  glClearDepth (1.0);
461 
462  //Finally, set the line width to something wide...
463  ChangeLineWidth(3.0);
464 
465 }
466 
467 void G4OpenGLViewer::HaloingSecondPass () {
468 
469  //And finally, turn the colour buffer back on with a sesible line width...
470  glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
471  glDepthFunc (GL_LEQUAL);
472  ChangeLineWidth(1.0);
473 
474 }
475 
476 G4String G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
477 {
478  const std::vector < G4OpenGLViewerPickMap* > & pickMap = GetPickDetails(x,y);
479  G4String txt = "";
480  if (pickMap.size() == 0) {
481 // txt += "No hits recorded.";;
482  } else {
483  for (unsigned int a=0; a < pickMap.size(); a++) {
484  if (pickMap[a]->getAttributes().size() > 0) {
485  txt += pickMap[a]->print();
486  }
487  }
488  }
489  return txt;
490 }
491 
492 const std::vector < G4OpenGLViewerPickMap* > & G4OpenGLViewer::GetPickDetails(GLdouble x, GLdouble y)
493 {
494  static std::vector < G4OpenGLViewerPickMap* > pickMapVector;
495  for (auto pickMap: pickMapVector) {
496  delete pickMap;
497  }
498  pickMapVector.clear();
499 
500  const G4int BUFSIZE = 512;
501  GLuint selectBuffer[BUFSIZE];
502  glSelectBuffer(BUFSIZE, selectBuffer);
503  glRenderMode(GL_SELECT);
504  glInitNames();
505  glPushName(0);
506  glMatrixMode(GL_PROJECTION);
507  G4double currentProjectionMatrix[16];
508  glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
509  glPushMatrix();
510  glLoadIdentity();
511  GLint viewport[4];
512  glGetIntegerv(GL_VIEWPORT, viewport);
513 /* G4cout
514  << "viewport, x,y: "
515  << viewport[0] << ',' << viewport[1] << ',' << viewport[2] << ',' << viewport[3]
516  << ", " << x << ',' << y
517  << G4endl;
518 */
519  fIsGettingPickInfos = true;
520  // Define 5x5 pixel pick area
521  g4GluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
522  glMultMatrixd(currentProjectionMatrix);
523  glMatrixMode(GL_MODELVIEW);
524  DrawView();
525  GLint hits = glRenderMode(GL_RENDER);
526  fIsGettingPickInfos = false;
527  if (hits < 0) {
528  G4cout << "Too many hits. Zoom in to reduce overlaps." << G4endl;
529  goto restoreMatrices;
530  }
531  if (hits > 0) {
532  GLuint* p = selectBuffer;
533  for (GLint i = 0; i < hits; ++i) {
534  GLuint nnames = *p++;
535  // This bit of debug code or...
536  //GLuint zmin = *p++;
537  //GLuint zmax = *p++;
538  //G4cout << "Hit " << i << ": " << nnames << " names"
539  // << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
540  // ...just increment the pointer
541  p++;
542  p++;
543  for (GLuint j = 0; j < nnames; ++j) {
544  GLuint name = *p++;
545  std::map<GLuint, G4AttHolder*>::iterator iter =
546  fOpenGLSceneHandler.fPickMap.find(name);
547  if (iter != fOpenGLSceneHandler.fPickMap.end()) {
548  G4AttHolder* attHolder = iter->second;
549  if(attHolder && attHolder->GetAttDefs().size()) {
550  for (size_t iAtt = 0;
551  iAtt < attHolder->GetAttDefs().size(); ++iAtt) {
552  std::ostringstream oss;
553  oss << G4AttCheck(attHolder->GetAttValues()[iAtt],
554  attHolder->GetAttDefs()[iAtt]);
555  G4OpenGLViewerPickMap* pickMap = new G4OpenGLViewerPickMap();
556 // G4cout
557 // << "i,j, attHolder->GetAttDefs().size(): "
558 // << i << ',' << j
559 // << ", " << attHolder->GetAttDefs().size()
560 // << G4endl;
561 // G4cout << "G4OpenGLViewer::GetPickDetails: " << oss.str() << G4endl;
562  pickMap->addAttributes(oss.str());
563  pickMap->setHitNumber(i);
564  pickMap->setSubHitNumber(j);
565  pickMap->setPickName(name);
566  pickMapVector.push_back(pickMap);
567  }
568  }
569  }
570  }
571  }
572  }
573 
574 restoreMatrices:
575  glMatrixMode(GL_PROJECTION);
576  glPopMatrix();
577  glMatrixMode(GL_MODELVIEW);
578 
579  return pickMapVector;
580 }
581 
582 GLubyte* G4OpenGLViewer::grabPixels
583 (int inColor, unsigned int width, unsigned int height) {
584 
585  GLubyte* buffer;
586  GLint swapbytes, lsbfirst, rowlength;
587  GLint skiprows, skippixels, alignment;
588  GLenum format;
589  int size;
590 
591  if (inColor) {
592  format = GL_RGB;
593  size = width*height*3;
594  } else {
595  format = GL_LUMINANCE;
596  size = width*height*1;
597  }
598 
599  buffer = new GLubyte[size];
600  if (buffer == NULL)
601  return NULL;
602 
603  glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
604  glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
605  glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
606 
607  glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
608  glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
609  glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
610 
611  glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
612  glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
613  glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
614 
615  glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
616  glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
617  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
618 
619  glReadBuffer(GL_FRONT);
620  glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
621 
622  glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
623  glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
624  glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
625 
626  glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
627  glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
628  glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
629 
630  return buffer;
631 }
632 
633 bool G4OpenGLViewer::printEPS() {
634  bool res;
635 
636  // Change the LC_NUMERIC value in order to have "." separtor and not ","
637  // This case is only useful for French, Canadien...
638  size_t len = strlen(setlocale(LC_NUMERIC,NULL));
639  char* oldLocale = (char*)(malloc(len+1));
640  if(oldLocale!=NULL) strncpy(oldLocale,setlocale(LC_NUMERIC,NULL),len);
641  setlocale(LC_NUMERIC,"C");
642 
643  if (((fExportImageFormat == "eps") || (fExportImageFormat == "ps")) && (!fVectoredPs)) {
644  res = printNonVectoredEPS();
645  } else {
646  res = printVectoredEPS();
647  }
648 
649  // restore the local
650  if (oldLocale) {
651  setlocale(LC_NUMERIC,oldLocale);
652  free(oldLocale);
653  }
654 
655  if (res == false) {
656  G4cerr << "Error saving file... " << getRealPrintFilename().c_str() << G4endl;
657  } else {
658  G4cout << "File " << getRealPrintFilename().c_str() << " size: " << getRealExportWidth() << "x" << getRealExportHeight() << " has been saved " << G4endl;
659 
660  // increment index if necessary
661  if ( fExportFilenameIndex != -1) {
662  fExportFilenameIndex++;
663  }
664  }
665 
666  return res;
667 }
668 
669 bool G4OpenGLViewer::printVectoredEPS() {
670  return printGl2PS();
671 }
672 
673 bool G4OpenGLViewer::printNonVectoredEPS () {
674 
675  int width = getRealExportWidth();
676  int height = getRealExportHeight();
677 
678  FILE* fp;
679  GLubyte* pixels;
680  GLubyte* curpix;
681  int components, pos, i;
682 
683  pixels = grabPixels (fPrintColour, width, height);
684 
685  if (pixels == NULL) {
686  G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
687  return false;
688  }
689  if (fPrintColour) {
690  components = 3;
691  } else {
692  components = 1;
693  }
694  std::string name = getRealPrintFilename();
695  fp = fopen (name.c_str(), "w");
696  if (fp == NULL) {
697  G4cerr << "Can't open filename " << name.c_str() << G4endl;
698  return false;
699  }
700 
701  fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
702  fprintf (fp, "%%%%Title: %s\n", name.c_str());
703  fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
704  fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
705  fprintf (fp, "%%%%EndComments\n");
706  fprintf (fp, "gsave\n");
707  fprintf (fp, "/bwproc {\n");
708  fprintf (fp, " rgbproc\n");
709  fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
710  fprintf (fp, " 5 -1 roll {\n");
711  fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
712  fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
713  fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
714  fprintf (fp, " { 2 1 roll } ifelse\n");
715  fprintf (fp, " }forall\n");
716  fprintf (fp, " pop pop pop\n");
717  fprintf (fp, "} def\n");
718  fprintf (fp, "systemdict /colorimage known not {\n");
719  fprintf (fp, " /colorimage {\n");
720  fprintf (fp, " pop\n");
721  fprintf (fp, " pop\n");
722  fprintf (fp, " /rgbproc exch def\n");
723  fprintf (fp, " { bwproc } image\n");
724  fprintf (fp, " } def\n");
725  fprintf (fp, "} if\n");
726  fprintf (fp, "/picstr %d string def\n", width * components);
727  fprintf (fp, "%d %d scale\n", width, height);
728  fprintf (fp, "%d %d %d\n", width, height, 8);
729  fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
730  fprintf (fp, "{currentfile picstr readhexstring pop}\n");
731  fprintf (fp, "false %d\n", components);
732  fprintf (fp, "colorimage\n");
733 
734  curpix = (GLubyte*) pixels;
735  pos = 0;
736  for (i = width*height*components; i>0; i--) {
737  fprintf (fp, "%02hx ", (unsigned short)(*(curpix++)));
738  if (++pos >= 32) {
739  fprintf (fp, "\n");
740  pos = 0;
741  }
742  }
743  if (pos)
744  fprintf (fp, "\n");
745 
746  fprintf (fp, "grestore\n");
747  fprintf (fp, "showpage\n");
748  delete [] pixels;
749  fclose (fp);
750 
751  // Reset for next time (useful is size change)
752  // fPrintSizeX = -1;
753  // fPrintSizeY = -1;
754 
755  return true;
756 }
757 
760 bool G4OpenGLViewer::isGl2psWriting() {
761 
762  if (!fGL2PSAction) return false;
763  if (fGL2PSAction->fileWritingEnabled()) {
764  return true;
765  }
766  return false;
767 }
768 
769 
770 G4bool G4OpenGLViewer::isFramebufferReady() {
771  bool check = false;
772 #ifdef G4VIS_BUILD_OPENGLQT_DRIVER
773  check = true;
774 #endif
775 #ifdef G4VIS_BUILD_OPENGLX_DRIVER
776  check = false;
777 #endif
778 #ifdef G4VIS_BUILD_OPENGLXM_DRIVER
779  check = false;
780 #endif
781 #ifdef G4VIS_BUILD_OPENGLWIN32_DRIVER
782  check = false;
783 #endif
784 
785 #if GL_ARB_framebuffer_object
786  if (check) {
787 // if ( glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNDEFINED) {
788 // return false;
789 // }
790  }
791 #endif
792  return true;
793 }
794 
795 
796 /* Draw Gl2Ps text if needed
797  */
798 void G4OpenGLViewer::DrawText(const G4Text& g4text)
799 {
800  // gl2ps or GL window ?
801  if (isGl2psWriting()) {
802 
804  G4double size = fSceneHandler.GetMarkerSize(g4text,sizeType);
805  G4Point3D position = g4text.GetPosition();
806 
807  G4String textString = g4text.GetText();
808 
809  glRasterPos3d(position.x(),position.y(),position.z());
810  GLint align = GL2PS_TEXT_B;
811 
812  switch (g4text.GetLayout()) {
813  case G4Text::left: align = GL2PS_TEXT_BL; break;
814  case G4Text::centre: align = GL2PS_TEXT_B; break;
815  case G4Text::right: align = GL2PS_TEXT_BR;
816  }
817 
818  gl2psTextOpt(textString.c_str(),"Times-Roman",GLshort(size),align,0);
819 
820  } else {
821 
822  static G4int callCount = 0;
823  ++callCount;
824  //if (callCount <= 10 || callCount%100 == 0) {
825  if (callCount <= 1) {
826  G4cout <<
827  "G4OpenGLViewer::DrawText: Not implemented for \""
828  << fName <<
829  "\"\n Called with "
830  << g4text
831  << G4endl;
832  }
833  }
834 }
835 
838 void G4OpenGLViewer::ChangePointSize(G4double size) {
839 
840  if (isGl2psWriting()) {
841  fGL2PSAction->setPointSize(int(size));
842  } else {
843  glPointSize (size);
844  }
845 }
846 
847 
850 void G4OpenGLViewer::ChangeLineWidth(G4double width) {
851 
852  if (isGl2psWriting()) {
853  fGL2PSAction->setLineWidth(int(width));
854  } else {
855  glLineWidth (width);
856  }
857 }
858 
867 bool G4OpenGLViewer::exportImage(std::string name, int width, int height) {
868 
869  if (! setExportFilename(name)) {
870  return false;
871  }
872 
873  if ((width != -1) && (height != -1)) {
874  setExportSize(width, height);
875  }
876 
877  if (fExportImageFormat == "eps") {
878  fGL2PSAction->setExportImageFormat(GL2PS_EPS);
879  } else if (fExportImageFormat == "ps") {
880  fGL2PSAction->setExportImageFormat(GL2PS_PS);
881  } else if (fExportImageFormat == "svg") {
882  fGL2PSAction->setExportImageFormat(GL2PS_SVG);
883  } else if (fExportImageFormat == "pdf") {
884  fGL2PSAction->setExportImageFormat(GL2PS_PDF);
885  } else {
886  setExportImageFormat(fExportImageFormat,true); // will display a message if this format is not correct for the current viewer
887  return false;
888  }
889  return printEPS();
890 }
891 
892 
893 bool G4OpenGLViewer::printGl2PS() {
894 
895  int width = getRealExportWidth();
896  int height = getRealExportHeight();
897  bool res = true;
898 
899  // no need to redraw at each new primitive for printgl2PS
900  G4OpenGLSceneHandler& oglSceneHandler = dynamic_cast<G4OpenGLSceneHandler&>(fSceneHandler);
901  G4OpenGLSceneHandler::FlushAction originalFlushAction = oglSceneHandler.GetFlushAction();
902  oglSceneHandler.SetFlushAction(G4OpenGLSceneHandler::never);
903 
904  if (!fGL2PSAction) return false;
905 
906  fGL2PSAction->setFileName(getRealPrintFilename().c_str());
907  // try to resize
908  int X = fWinSize_x;
909  int Y = fWinSize_y;
910 
911  fWinSize_x = width;
912  fWinSize_y = height;
913  // Laurent G. 16/03/10 : Not the good way to do.
914  // We should draw in a new offscreen context instead of
915  // resizing and drawing in current window...
916  // This should be solve when we will do an offscreen method
917  // to render OpenGL
918  // See :
919  // http://developer.apple.com/Mac/library/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_offscreen/opengl_offscreen.html
920  // http://www.songho.ca/opengl/gl_fbo.html
921 
922  ResizeGLView();
923  bool extendBuffer = true;
924  bool endWriteAction = false;
925  bool beginWriteAction = true;
926  bool filePointerOk = true;
927  while ((extendBuffer) && (! endWriteAction) && (filePointerOk)) {
928 
929  beginWriteAction = fGL2PSAction->enableFileWriting();
930  // 3 cases :
931  // - true
932  // - false && ! fGL2PSAction->fileWritingEnabled() => bad file name
933  // - false && fGL2PSAction->fileWritingEnabled() => buffer size problem ?
934 
935  filePointerOk = fGL2PSAction->fileWritingEnabled();
936 
937  if (beginWriteAction) {
938 
939  // Set the viewport
940  // By default, we choose the line width (trajectories...)
941  fGL2PSAction->setLineWidth(fGl2psDefaultLineWith);
942  // By default, we choose the point size (markers...)
943  fGL2PSAction->setPointSize(fGl2psDefaultPointSize);
944 
945  DrawView ();
946  endWriteAction = fGL2PSAction->disableFileWriting();
947  }
948  if (filePointerOk) {
949  if ((! endWriteAction) || (! beginWriteAction)) {
950  extendBuffer = fGL2PSAction->extendBufferSize();
951  }
952  }
953  }
954  fGL2PSAction->resetBufferSizeParameters();
955 
956  if (!extendBuffer ) {
957  G4cerr << "ERROR: gl2ps buffer size is not big enough to print this geometry. Try to extend it. No output produced"<< G4endl;
958  res = false;
959  }
960  if (!beginWriteAction ) {
961  G4cerr << "ERROR: saving file "<<getRealPrintFilename().c_str()<<". Check read/write access. No output produced" << G4endl;
962  res = false;
963  }
964  if (!endWriteAction ) {
965  G4cerr << "gl2ps error. No output produced" << G4endl;
966  res = false;
967  }
968  fWinSize_x = X;
969  fWinSize_y = Y;
970 
971  oglSceneHandler.SetFlushAction(originalFlushAction);
972 
973  // Reset for next time (useful is size change)
974  // fPrintSizeX = 0;
975  // fPrintSizeY = 0;
976 
977  return res;
978 }
979 
980 unsigned int G4OpenGLViewer::getWinWidth() const{
981  return fWinSize_x;
982 }
983 
984 unsigned int G4OpenGLViewer::getWinHeight() const{
985  return fWinSize_y;
986 }
987 
988 G4bool G4OpenGLViewer::sizeHasChanged() {
989  return fSizeHasChanged;
990 }
991 
992 G4int G4OpenGLViewer::getRealExportWidth() {
993  if (fPrintSizeX == -1) {
994  return fWinSize_x;
995  }
996  GLint dims[2];
997  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
998 
999  // L.Garnier 01-2010: Some problems with mac 10.6
1000  if ((dims[0] !=0 ) && (dims[1] !=0)) {
1001  if (fPrintSizeX > dims[0]){
1002  return dims[0];
1003  }
1004  }
1005  if (fPrintSizeX < -1){
1006  return 0;
1007  }
1008  return fPrintSizeX;
1009 }
1010 
1011 G4int G4OpenGLViewer::getRealExportHeight() {
1012  if (fPrintSizeY == -1) {
1013  return fWinSize_y;
1014  }
1015  GLint dims[2];
1016  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
1017 
1018  // L.Garnier 01-2010: Some problems with mac 10.6
1019  if ((dims[0] !=0 ) && (dims[1] !=0)) {
1020  if (fPrintSizeY > dims[1]){
1021  return dims[1];
1022  }
1023  }
1024  if (fPrintSizeY < -1){
1025  return 0;
1026  }
1027  return fPrintSizeY;
1028 }
1029 
1030 void G4OpenGLViewer::setExportSize(G4int X, G4int Y) {
1031  fPrintSizeX = X;
1032  fPrintSizeY = Y;
1033 }
1034 
1041 bool G4OpenGLViewer::setExportFilename(G4String name,G4bool inc) {
1042  if (name == "!") {
1043  name = "";
1044  }
1045 
1046  if (inc) {
1047  if ((name != "") && (fExportFilename != name)) {
1048  fExportFilenameIndex=0;
1049  }
1050  } else {
1051  fExportFilenameIndex=-1;
1052  }
1053 
1054  if (name.size() == 0) {
1055  name = getRealPrintFilename().c_str();
1056  } else {
1057  // guess format by extention
1058  std::string extension = name.substr(name.find_last_of(".") + 1);
1059  // no format
1060  if (name.size() != extension.size()) {
1061  if (! setExportImageFormat(extension, false)) {
1062  return false;
1063  }
1064  }
1065  // get the name
1066  fExportFilename = name.substr(0,name.find_last_of("."));
1067  }
1068  return true;
1069 }
1070 
1071 std::string G4OpenGLViewer::getRealPrintFilename() {
1072  std::string temp = fExportFilename;
1073  if (fExportFilenameIndex != -1) {
1074  temp += std::string("_");
1075  std::ostringstream os;
1076  os << std::setw(4) << std::setfill('0') << fExportFilenameIndex;
1077  std::string nb_str = os.str();
1078  temp += nb_str;
1079  }
1080  temp += "."+fExportImageFormat;
1081  return temp;
1082 }
1083 
1084 GLdouble G4OpenGLViewer::getSceneNearWidth()
1085 {
1086  if (!fSceneHandler.GetScene()) {
1087  return 0;
1088  }
1089  const G4Point3D targetPoint
1090  = fSceneHandler.GetScene()->GetStandardTargetPoint()
1091  + fVP.GetCurrentTargetPoint ();
1092  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1093  if(radius<=0.) radius = 1.;
1094  const G4double cameraDistance = fVP.GetCameraDistance (radius);
1095  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1096  return 2 * fVP.GetFrontHalfHeight (pnear, radius);
1097 }
1098 
1099 GLdouble G4OpenGLViewer::getSceneFarWidth()
1100 {
1101  if (!fSceneHandler.GetScene()) {
1102  return 0;
1103  }
1104  const G4Point3D targetPoint
1105  = fSceneHandler.GetScene()->GetStandardTargetPoint()
1106  + fVP.GetCurrentTargetPoint ();
1107  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1108  if(radius<=0.) radius = 1.;
1109  const G4double cameraDistance = fVP.GetCameraDistance (radius);
1110  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1111  const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
1112  return 2 * fVP.GetFrontHalfHeight (pfar, radius);
1113 }
1114 
1115 
1116 GLdouble G4OpenGLViewer::getSceneDepth()
1117 {
1118  if (!fSceneHandler.GetScene()) {
1119  return 0;
1120  }
1121  const G4Point3D targetPoint
1122  = fSceneHandler.GetScene()->GetStandardTargetPoint()
1123  + fVP.GetCurrentTargetPoint ();
1124  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1125  if(radius<=0.) radius = 1.;
1126  const G4double cameraDistance = fVP.GetCameraDistance (radius);
1127  const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1128  return fVP.GetFarDistance (cameraDistance, pnear, radius)- pnear;
1129 }
1130 
1131 
1132 
1133 void G4OpenGLViewer::rotateScene(G4double dx, G4double dy)
1134 {
1135  if (fVP.GetRotationStyle() == G4ViewParameters::freeRotation) {
1136  rotateSceneInViewDirection(dx,dy);
1137  } else {
1138  if( dx != 0) {
1139  rotateSceneThetaPhi(dx,0);
1140  }
1141  if( dy != 0) {
1142  rotateSceneThetaPhi(0,dy);
1143  }
1144  }
1145 }
1146 
1147 
1148 void G4OpenGLViewer::rotateSceneToggle(G4double dx, G4double dy)
1149 {
1150  if (fVP.GetRotationStyle() != G4ViewParameters::freeRotation) {
1151  rotateSceneInViewDirection(dx,dy);
1152  } else {
1153  if( dx != 0) {
1154  rotateSceneThetaPhi(dx,0);
1155  }
1156  if( dy != 0) {
1157  rotateSceneThetaPhi(0,dy);
1158  }
1159  }
1160 }
1161 
1162 void G4OpenGLViewer::rotateSceneThetaPhi(G4double dx, G4double dy)
1163 {
1164  if (!fSceneHandler.GetScene()) {
1165  return;
1166  }
1167 
1168  G4Vector3D vp;
1169  G4Vector3D up;
1170 
1171  G4Vector3D xprime;
1172  G4Vector3D yprime;
1173  G4Vector3D zprime;
1174 
1175  G4double delta_alpha;
1176  G4double delta_theta;
1177 
1178  G4Vector3D new_vp;
1179  G4Vector3D new_up;
1180 
1181  G4double cosalpha;
1182  G4double sinalpha;
1183 
1184  G4Vector3D a1;
1185  G4Vector3D a2;
1186  G4Vector3D delta;
1187  G4Vector3D viewPoint;
1188 
1189 
1190  //phi spin stuff here
1191 
1192  vp = fVP.GetViewpointDirection ().unit ();
1193  up = fVP.GetUpVector ().unit ();
1194 
1195  yprime = (up.cross(vp)).unit();
1196  zprime = (vp.cross(yprime)).unit();
1197 
1198  if (fVP.GetLightsMoveWithCamera()) {
1199  delta_alpha = dy * fRot_sens;
1200  delta_theta = -dx * fRot_sens;
1201  } else {
1202  delta_alpha = -dy * fRot_sens;
1203  delta_theta = dx * fRot_sens;
1204  }
1205 
1206  delta_alpha *= deg;
1207  delta_theta *= deg;
1208 
1209  new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1210 
1211  // to avoid z rotation flipping
1212  // to allow more than 360∞ rotation
1213 
1214  if (fVP.GetLightsMoveWithCamera()) {
1215  new_up = (new_vp.cross(yprime)).unit();
1216  if (new_vp.z()*vp.z() <0) {
1217  new_up.set(new_up.x(),-new_up.y(),new_up.z());
1218  }
1219  } else {
1220  new_up = up;
1221  if (new_vp.z()*vp.z() <0) {
1222  new_up.set(new_up.x(),-new_up.y(),new_up.z());
1223  }
1224  }
1225  fVP.SetUpVector(new_up);
1227  // Rotates by fixed azimuthal angle delta_theta.
1228 
1229  cosalpha = new_up.dot (new_vp.unit());
1230  sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1231  yprime = (new_up.cross (new_vp.unit())).unit ();
1232  xprime = yprime.cross (new_up);
1233  // Projection of vp on plane perpendicular to up...
1234  a1 = sinalpha * xprime;
1235  // Required new projection...
1236  a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1237  // Required Increment vector...
1238  delta = a2 - a1;
1239  // So new viewpoint is...
1240  viewPoint = new_vp.unit() + delta;
1241 
1242  fVP.SetViewAndLights (viewPoint);
1243 }
1244 
1245 
1246 void G4OpenGLViewer::rotateSceneInViewDirection(G4double dx, G4double dy)
1247 {
1248  if (!fSceneHandler.GetScene()) {
1249  return;
1250  }
1251 
1252  G4Vector3D vp;
1253  G4Vector3D up;
1254 
1255  G4Vector3D xprime;
1256  G4Vector3D yprime;
1257  G4Vector3D zprime;
1258 
1259  G4Vector3D new_vp;
1260  G4Vector3D new_up;
1261 
1262  G4Vector3D a1;
1263  G4Vector3D a2;
1264  G4Vector3D delta;
1265  G4Vector3D viewPoint;
1266 
1267  dx = dx/100;
1268  dy = dy/100;
1269 
1270  //phi spin stuff here
1271 
1272  vp = fVP.GetViewpointDirection ().unit();
1273  up = fVP.GetUpVector ().unit();
1274 
1275  G4Vector3D zPrimeVector = G4Vector3D(up.y()*vp.z()-up.z()*vp.y(),
1276  up.z()*vp.x()-up.x()*vp.z(),
1277  up.x()*vp.y()-up.y()*vp.x());
1278 
1279  viewPoint = vp/fRot_sens + (zPrimeVector*dx - up*dy) ;
1280  new_up = G4Vector3D(viewPoint.y()*zPrimeVector.z()-viewPoint.z()*zPrimeVector.y(),
1281  viewPoint.z()*zPrimeVector.x()-viewPoint.x()*zPrimeVector.z(),
1282  viewPoint.x()*zPrimeVector.y()-viewPoint.y()*zPrimeVector.x());
1283 
1284  G4Vector3D new_upUnit = new_up.unit();
1285 
1286 
1287 
1288  fVP.SetUpVector(new_upUnit);
1289  fVP.SetViewAndLights (viewPoint);
1290 }
1291 
1292 
1293 void G4OpenGLViewer::addExportImageFormat(std::string format) {
1294  fExportImageFormatVector.push_back(format);
1295 }
1296 
1297 bool G4OpenGLViewer::setExportImageFormat(std::string format, bool quiet) {
1298  bool found = false;
1299  std::string list;
1300  for (unsigned int a=0; a<fExportImageFormatVector.size(); a++) {
1301  list +=fExportImageFormatVector.at(a) + " ";
1302 
1303  if (fExportImageFormatVector.at(a) == format) {
1304  if (! quiet) {
1305  G4cout << " Changing export format to \"" << format << "\"" << G4endl;
1306  }
1307  if (format != fExportImageFormat) {
1308  fExportFilenameIndex = 0;
1309  fExportImageFormat = format;
1310  }
1311  return true;
1312  }
1313  }
1314  if (! found) {
1315  if (format.size() == 0) {
1316  G4cout << " Current formats availables are : " << list << G4endl;
1317  } else {
1318  G4cerr << " Format \"" << format << "\" is not available for the selected viewer. Current formats availables are : " << list << G4endl;
1319  }
1320  }
1321  return false;
1322 }
1323 
1324 
1325 // From MESA implementation :
1326 // http://www.techques.com/question/1-8660454/gluPickMatrix-code-from-Mesa
1327 
1328 void G4OpenGLViewer::g4GluPickMatrix(GLdouble x, GLdouble y, GLdouble width, GLdouble height,
1329  GLint viewport[4])
1330  {
1331  GLdouble mat[16];
1332  GLdouble sx, sy;
1333  GLdouble tx, ty;
1334 
1335  sx = viewport[2] / width;
1336  sy = viewport[3] / height;
1337  tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
1338  ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
1339 
1340 #define M(row, col) mat[col*4+row]
1341  M(0, 0) = sx;
1342  M(0, 1) = 0.0;
1343  M(0, 2) = 0.0;
1344  M(0, 3) = tx;
1345  M(1, 0) = 0.0;
1346  M(1, 1) = sy;
1347  M(1, 2) = 0.0;
1348  M(1, 3) = ty;
1349  M(2, 0) = 0.0;
1350  M(2, 1) = 0.0;
1351  M(2, 2) = 1.0;
1352  M(2, 3) = 0.0;
1353  M(3, 0) = 0.0;
1354  M(3, 1) = 0.0;
1355  M(3, 2) = 0.0;
1356  M(3, 3) = 1.0;
1357 #undef M
1358 
1359  glMultMatrixd(mat);
1360 }
1361 
1362 
1363 
1364 
1365 
1366 // From MESA implementation :
1367 // https://github.com/jlamarche/iOS-OpenGLES-Stuff/blob/master/Wavefront%20OBJ%20Loader/Classes/gluLookAt.m
1368 // or http://www.daniweb.com/software-development/game-development/threads/308901/lookat-matrix-source-code
1369 
1370 void G4OpenGLViewer::g4GluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
1371  GLdouble centerx, GLdouble centery, GLdouble
1372  centerz,
1373  GLdouble upx, GLdouble upy, GLdouble upz )
1374 {
1375  GLdouble mat[16];
1376  GLdouble x[3], y[3], z[3];
1377  GLdouble mag;
1378 
1379  /* Make rotation matrix */
1380 
1381  /* Z vector */
1382  z[0] = eyex - centerx;
1383  z[1] = eyey - centery;
1384  z[2] = eyez - centerz;
1385  mag = std::sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
1386  if (mag) { /* mpichler, 19950515 */
1387  z[0] /= mag;
1388  z[1] /= mag;
1389  z[2] /= mag;
1390  }
1391 
1392  /* Y vector */
1393  y[0] = upx;
1394  y[1] = upy;
1395  y[2] = upz;
1396 
1397  /* X vector = Y cross Z */
1398  x[0] = y[1] * z[2] - y[2] * z[1];
1399  x[1] = -y[0] * z[2] + y[2] * z[0];
1400  x[2] = y[0] * z[1] - y[1] * z[0];
1401 
1402  /* Recompute Y = Z cross X */
1403  y[0] = z[1] * x[2] - z[2] * x[1];
1404  y[1] = -z[0] * x[2] + z[2] * x[0];
1405  y[2] = z[0] * x[1] - z[1] * x[0];
1406 
1407  /* mpichler, 19950515 */
1408  /* cross product gives area of parallelogram, which is < 1.0 for
1409  * non-perpendicular unit-length vectors; so normalize x, y here
1410  */
1411 
1412  mag = std::sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
1413  if (mag) {
1414  x[0] /= mag;
1415  x[1] /= mag;
1416  x[2] /= mag;
1417  }
1418 
1419  mag = std::sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
1420  if (mag) {
1421  y[0] /= mag;
1422  y[1] /= mag;
1423  y[2] /= mag;
1424  }
1425 
1426 #define M(row,col) mat[col*4+row]
1427  M(0, 0) = x[0];
1428  M(0, 1) = x[1];
1429  M(0, 2) = x[2];
1430  M(0, 3) = 0.0;
1431  M(1, 0) = y[0];
1432  M(1, 1) = y[1];
1433  M(1, 2) = y[2];
1434  M(1, 3) = 0.0;
1435  M(2, 0) = z[0];
1436  M(2, 1) = z[1];
1437  M(2, 2) = z[2];
1438  M(2, 3) = 0.0;
1439  M(3, 0) = 0.0;
1440  M(3, 1) = 0.0;
1441  M(3, 2) = 0.0;
1442  M(3, 3) = 1.0;
1443 #undef M
1444  glMultMatrixd(mat);
1445 
1446  /* Translate Eye to Origin */
1447  glTranslated(-eyex, -eyey, -eyez);
1448 }
1449 
1450 void G4OpenGLViewer::g4GlOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) {
1451  // glOrtho (left, right, bottom, top, near, far);
1452 
1453  GLdouble a = 2.0 / (right - left);
1454  GLdouble b = 2.0 / (top - bottom);
1455  GLdouble c = -2.0 / (zFar - zNear);
1456 
1457  GLdouble tx = - (right + left)/(right - left);
1458  GLdouble ty = - (top + bottom)/(top - bottom);
1459  GLdouble tz = - (zFar + zNear)/(zFar - zNear);
1460 
1461  GLdouble ortho[16] = {
1462  a, 0, 0, 0,
1463  0, b, 0, 0,
1464  0, 0, c, 0,
1465  tx, ty, tz, 1
1466  };
1467  glMultMatrixd(ortho);
1468 
1469 }
1470 
1471 
1472 void G4OpenGLViewer::g4GlFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) {
1473  // glFrustum (left, right, bottom, top, near, far);
1474 
1475  GLdouble deltaX = right - left;
1476  GLdouble deltaY = top - bottom;
1477  GLdouble deltaZ = zFar - zNear;
1478 
1479  GLdouble a = 2.0f * zNear / deltaX;
1480  GLdouble b = 2.0f * zNear / deltaY;
1481  GLdouble c = (right + left) / deltaX;
1482  GLdouble d = (top + bottom) / deltaY;
1483  GLdouble e = -(zFar + zNear) / (zFar - zNear);
1484  GLdouble f = -2.0f * zFar * zNear / deltaZ;
1485 
1486  GLdouble proj[16] = {
1487  a, 0, 0, 0,
1488  0, b, 0, 0,
1489  c, d, e, -1.0f,
1490  0, 0, f, 0
1491  };
1492 
1493  glMultMatrixd(proj);
1494 
1495 }
1496 
1497 
1498 #ifdef G4OPENGL_VERSION_2
1499 
1500 // Associate the VBO drawer to the OpenGLViewer and the OpenGLSceneHandler
1501 void G4OpenGLViewer::setVboDrawer(G4OpenGLVboDrawer* drawer) {
1502  fVboDrawer = drawer;
1503  try {
1504  G4OpenGLSceneHandler& sh = dynamic_cast<G4OpenGLSceneHandler&>(fSceneHandler);
1505  sh.setVboDrawer(fVboDrawer);
1506  } catch(std::bad_cast exp) { }
1507 }
1508 
1509 #endif
1510 
1511 
1513  std::ostringstream txt;
1514  for (unsigned int a=0; a<fAttributes.size(); a++) {
1515  txt << fAttributes[a];
1516  if (a < fAttributes.size() - 1) txt << "\n";
1517  }
1518  return txt.str();
1519 }
1520 
1521 #endif
Float_t x
Definition: compare.C:6
const XML_Char int len
Definition: expat.h:262
#define GL2PS_PS
Definition: gl2ps.h:119
const XML_Char * name
Definition: expat.h:151
void print(G4double elem)
G4String GetText() const
std::vector< ExP01TrackerHit * > a
Definition: ExP01Classes.hh:33
static const G4double pos
BasicVector3D< T > unit() const
#define G4endl
Definition: G4ios.hh:61
Float_t y
Definition: compare.C:6
const char * p
Definition: xmltok.h:285
Double_t z
Float_t Y
BasicVector3D< T > cross(const BasicVector3D< T > &v) const
#define buffer
Definition: xmlparse.cc:628
const std::vector< const std::map< G4String, G4AttDef > * > & GetAttDefs() const
Definition: G4AttHolder.hh:62
#define GL2PS_TEXT_BL
Definition: gl2ps.h:176
fclose(fg1)
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
#define width
void hits()
Definition: readHits.C:15
#define GL2PS_TEXT_BR
Definition: gl2ps.h:177
Definition: G4Text.hh:73
Layout GetLayout() const
static constexpr double deg
Definition: G4SIunits.hh:152
GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, GLshort fontsize, GLint align, GLfloat angle)
Float_t d
T dot(const BasicVector3D< T > &v) const
Float_t mat
Double_t radius
G4String fName
Definition: G4AttUtils.hh:55
FILE * fp
G4GLOB_DLL std::ostream G4cerr
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
#define GL2PS_PDF
Definition: gl2ps.h:122
const std::vector< const std::vector< G4AttValue > * > & GetAttValues() const
Definition: G4AttHolder.hh:60
int G4int
Definition: G4Types.hh:78
void set(T x1, T y1, T z1)
#define GL2PS_TEXT_B
Definition: gl2ps.h:175
#define GL2PS_SVG
Definition: gl2ps.h:123
G4GLOB_DLL std::ostream G4cout
G4Point3D GetPosition() const
Float_t X
std::vector< G4Plane3D > G4Planes
virtual void ResetView()
#define GL2PS_EPS
Definition: gl2ps.h:120