source: trunk/source/visualization/OpenGL/src/G4OpenGLViewer.cc @ 1047

Last change on this file since 1047 was 1046, checked in by garnier, 15 years ago

update

  • Property svn:mime-type set to text/cpp
File size: 24.4 KB
Line 
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,v 1.56 2009/05/14 16:38:23 lgarnier Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// Andrew Walkden  27th March 1996
32// OpenGL view - opens window, hard copy, etc.
33
34#ifdef G4VIS_BUILD_OPENGL_DRIVER
35
36#include "G4ios.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
52// GL2PS
53#include "Geant4_gl2ps.h"
54
55#include <sstream>
56
57G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
58G4VViewer (scene, -1),
59fPrintColour (true),
60fVectoredPs (true),
61fOpenGLSceneHandler(scene),
62background (G4Colour(0.,0.,0.)),
63transparency_enabled (true),
64antialiasing_enabled (false),
65haloing_enabled (false),
66fStartTime(-DBL_MAX),
67fEndTime(DBL_MAX),
68fFadeFactor(0.),
69fDisplayHeadTime(false),
70fDisplayHeadTimeX(-0.9),
71fDisplayHeadTimeY(-0.9),
72fDisplayHeadTimeSize(24.),
73fDisplayHeadTimeRed(0.),
74fDisplayHeadTimeGreen(1.),
75fDisplayHeadTimeBlue(1.),
76fDisplayLightFront(false),
77fDisplayLightFrontX(0.),
78fDisplayLightFrontY(0.),
79fDisplayLightFrontZ(0.),
80fDisplayLightFrontT(0.),
81fDisplayLightFrontRed(0.),
82fDisplayLightFrontGreen(1.),
83fDisplayLightFrontBlue(0.),
84fPrintSizeX(-1),
85fPrintSizeY(-1),
86fPrintFilename ("G4OpenGL"),
87fPrintFilenameIndex(0),
88fPointSize (0),
89fSizeHasChanged(0)
90{
91  // Make changes to view parameters for OpenGL...
92  fVP.SetAutoRefresh(true);
93  fDefaultVP.SetAutoRefresh(true);
94  fWinSize_x = fVP.GetWindowSizeHintX();
95  fWinSize_y = fVP.GetWindowSizeHintY();
96
97  fGL2PSAction = new G4OpenGL2PSAction();
98
99  //  glClearColor (0.0, 0.0, 0.0, 0.0);
100  //  glClearDepth (1.0);
101  //  glDisable (GL_BLEND);
102  //  glDisable (GL_LINE_SMOOTH);
103  //  glDisable (GL_POLYGON_SMOOTH);
104
105}
106
107G4OpenGLViewer::~G4OpenGLViewer () {}
108
109void G4OpenGLViewer::InitializeGLView ()
110{
111  glClearColor (0.0, 0.0, 0.0, 0.0);
112  glClearDepth (1.0);
113  glDisable (GL_BLEND);
114  glDisable (GL_LINE_SMOOTH);
115  glDisable (GL_POLYGON_SMOOTH);
116
117
118void G4OpenGLViewer::ClearView () {
119#ifdef G4DEBUG_VIS_OGL
120  printf("G4OpenGLViewer::ClearView\n");
121#endif
122  glClearColor (background.GetRed(),
123                background.GetGreen(),
124                background.GetBlue(),
125                1.);
126  glClearDepth (1.0);
127  //Below line does not compile with Mesa includes.
128  //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
129  glClear (GL_COLOR_BUFFER_BIT);
130  glClear (GL_DEPTH_BUFFER_BIT);
131  glClear (GL_STENCIL_BUFFER_BIT);
132#ifdef G4DEBUG_VIS_OGL
133  printf("G4OpenGLViewer::ClearView flush\n");
134#endif
135  glFlush ();
136}
137
138
139void G4OpenGLViewer::ResizeWindow(unsigned int aWidth, unsigned int aHeight) {
140  if ((fWinSize_x != aWidth) || (fWinSize_y != aHeight)) {
141    fWinSize_x = aWidth;
142    fWinSize_y = aHeight;
143    fSizeHasChanged = true;
144  } else {
145    fSizeHasChanged = false;
146  }
147}
148
149/**
150 * Set the viewport of the scene
151 * MAXIMUM SIZE is :
152 * GLint dims[2];
153 * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
154 */
155void G4OpenGLViewer::ResizeGLView()
156{
157#ifdef G4DEBUG_VIS_OGL
158  printf("G4OpenGLViewer::ResizeGLView %d %d\n",fWinSize_x,fWinSize_y);
159#endif
160  // Check size
161  GLint dims[2];
162  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
163  if (fWinSize_x > (unsigned)dims[0]) {
164    G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<dims[0] <<" is resize to "<<  dims[0] << G4endl;
165    fWinSize_x = dims[0];
166  }
167  if (fWinSize_y > (unsigned)dims[1]) {
168    G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<dims[0] <<" is resize to "<<  dims[1] << G4endl;
169    fWinSize_y = dims[1];
170  }
171  GLsizei side = fWinSize_x;
172  if (fWinSize_y < fWinSize_x) side = fWinSize_y;
173
174  // SPECIAL CASE if fWinSize_x is even (69 for example)
175  // Ex : X: 69 Y: 26
176  // side = 26
177  // width / 2 = 21,5
178  // height / 2 = 0
179  // Should be fixed to closed : 21 0 for ex
180  // Then size must by change to :
181  // X:68 Y: 26
182
183  // SPECIAL CASE
184  if ((fWinSize_x - side)%2) {
185    //    fWinSize_x --;
186
187    side = fWinSize_x;
188    if (fWinSize_y < fWinSize_x) side = fWinSize_y;
189  }
190  if ((fWinSize_y - side)%2) {
191    //    fWinSize_y --;
192
193    side = fWinSize_x;
194    if (fWinSize_y < fWinSize_x) side = fWinSize_y;
195  }
196 
197  GLint X = (fWinSize_x - side) / 2;
198  GLint Y = (fWinSize_y - side) / 2;
199 
200#ifdef G4DEBUG_VIS_OGL
201  printf("G4OpenGLViewer::ResizeGLView X:%d Y:%d W:%d H:%d --side%d\n",(fWinSize_x - side) / 2,(fWinSize_y - side) / 2,fWinSize_x,fWinSize_y,side);
202#endif
203  glViewport(X, Y, side, side);
204  //    glViewport(0, 0, fWinSize_x,fWinSize_y); 
205 
206
207}
208
209
210void G4OpenGLViewer::SetView () {
211
212  if (!fSceneHandler.GetScene()) {
213    G4cerr << "G4OpenGLStoredViewer: Creating a Viewer without a scene is not allowed. \nPlease use /vis/scene/create before /vis/open/.... "
214           << G4endl;
215    return;
216  }
217  // Calculates view representation based on extent of object being
218  // viewed and (initial) viewpoint.  (Note: it can change later due
219  // to user interaction via visualization system's GUI.)
220 
221  // Lighting.
222  GLfloat lightPosition [4];
223  lightPosition [0] = fVP.GetActualLightpointDirection().x();
224  lightPosition [1] = fVP.GetActualLightpointDirection().y();
225  lightPosition [2] = fVP.GetActualLightpointDirection().z();
226  lightPosition [3] = 0.;
227  // Light position is "true" light direction, so must come after gluLookAt.
228  GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.};
229  GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.};
230  glEnable (GL_LIGHT0);
231  glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
232  glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
233 
234  // Get radius of scene, etc.
235  // Note that this procedure properly takes into account zoom, dolly and pan.
236  const G4Point3D targetPoint
237    = fSceneHandler.GetScene()->GetStandardTargetPoint()
238    + fVP.GetCurrentTargetPoint ();
239  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
240  if(radius<=0.) radius = 1.;
241  const G4double cameraDistance = fVP.GetCameraDistance (radius);
242  const G4Point3D cameraPosition =
243    targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
244  const GLdouble pnear  = fVP.GetNearDistance (cameraDistance, radius);
245  const GLdouble pfar   = fVP.GetFarDistance  (cameraDistance, pnear, radius);
246  const GLdouble right  = fVP.GetFrontHalfHeight (pnear, radius);
247  const GLdouble left   = -right;
248  const GLdouble bottom = left;
249  const GLdouble top    = right;
250 
251  // FIXME
252  ResizeGLView();
253  //SHOULD SetWindowsSizeHint()...
254
255  glMatrixMode (GL_PROJECTION); // set up Frustum.
256  glLoadIdentity();
257
258  const G4Vector3D scaleFactor = fVP.GetScaleFactor();
259  glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
260 
261  if (fVP.GetFieldHalfAngle() == 0.) {
262    glOrtho (left, right, bottom, top, pnear, pfar);
263  }
264  else {
265    glFrustum (left, right, bottom, top, pnear, pfar);
266  } 
267
268  glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
269  glLoadIdentity();
270 
271  const G4Normal3D& upVector = fVP.GetUpVector (); 
272  G4Point3D gltarget;
273  if (cameraDistance > 1.e-6 * radius) {
274    gltarget = targetPoint;
275  }
276  else {
277    gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
278  }
279
280  const G4Point3D& pCamera = cameraPosition;  // An alias for brevity.
281  gluLookAt (pCamera.x(),  pCamera.y(),  pCamera.z(),       // Viewpoint.
282             gltarget.x(), gltarget.y(), gltarget.z(),      // Target point.
283             upVector.x(), upVector.y(), upVector.z());     // Up vector.
284
285  // Light position is "true" light direction, so must come after gluLookAt.
286  glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
287
288  // OpenGL no longer seems to reconstruct clipped edges, so, when the
289  // BooleanProcessor is up to it, abandon this and use generic
290  // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron.  Also,
291  // force kernel visit on change of clipping plane in
292  // G4OpenGLStoredViewer::CompareForKernelVisit.
293  if (fVP.IsSection () ) {  // pair of back to back clip planes.
294    const G4Plane3D& s = fVP.GetSectionPlane ();
295    double sArray[4];
296    sArray[0] = s.a();
297    sArray[1] = s.b();
298    sArray[2] = s.c();
299    sArray[3] = s.d() + radius * 1.e-05;
300    glClipPlane (GL_CLIP_PLANE0, sArray);
301    glEnable (GL_CLIP_PLANE0);
302    sArray[0] = -s.a();
303    sArray[1] = -s.b();
304    sArray[2] = -s.c();
305    sArray[3] = -s.d() + radius * 1.e-05;
306    glClipPlane (GL_CLIP_PLANE1, sArray);
307    glEnable (GL_CLIP_PLANE1);
308  } else {
309    glDisable (GL_CLIP_PLANE0);
310    glDisable (GL_CLIP_PLANE1);
311  }
312
313  const G4Planes& cutaways = fVP.GetCutawayPlanes();
314  size_t nPlanes = cutaways.size();
315  if (fVP.IsCutaway() &&
316      fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
317      nPlanes > 0) {
318    double a[4];
319    a[0] = cutaways[0].a();
320    a[1] = cutaways[0].b();
321    a[2] = cutaways[0].c();
322    a[3] = cutaways[0].d();
323    glClipPlane (GL_CLIP_PLANE2, a);
324    glEnable (GL_CLIP_PLANE2);
325    if (nPlanes > 1) {
326      a[0] = cutaways[1].a();
327      a[1] = cutaways[1].b();
328      a[2] = cutaways[1].c();
329      a[3] = cutaways[1].d();
330      glClipPlane (GL_CLIP_PLANE3, a);
331      glEnable (GL_CLIP_PLANE3);
332    }
333    if (nPlanes > 2) {
334      a[0] = cutaways[2].a();
335      a[1] = cutaways[2].b();
336      a[2] = cutaways[2].c();
337      a[3] = cutaways[2].d();
338      glClipPlane (GL_CLIP_PLANE4, a);
339      glEnable (GL_CLIP_PLANE4);
340    }
341  } else {
342    glDisable (GL_CLIP_PLANE2);
343    glDisable (GL_CLIP_PLANE3);
344    glDisable (GL_CLIP_PLANE4);
345  }
346
347  // Background.
348  background = fVP.GetBackgroundColour ();
349
350}
351
352void G4OpenGLViewer::HaloingFirstPass () {
353 
354  //To perform haloing, first Draw all information to the depth buffer
355  //alone, using a chunky line width, and then Draw all info again, to
356  //the colour buffer, setting a thinner line width an the depth testing
357  //function to less than or equal, so if two lines cross, the one
358  //passing behind the other will not pass the depth test, and so not
359  //get rendered either side of the infront line for a short distance.
360
361  //First, disable writing to the colo(u)r buffer...
362  glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
363
364  //Now enable writing to the depth buffer...
365  glDepthMask (GL_TRUE);
366  glDepthFunc (GL_LESS);
367  glClearDepth (1.0);
368
369  //Finally, set the line width to something wide...
370  glLineWidth (3.0);
371
372}
373
374void G4OpenGLViewer::HaloingSecondPass () {
375
376  //And finally, turn the colour buffer back on with a sesible line width...
377  glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
378  glDepthFunc (GL_LEQUAL);
379  glLineWidth (1.0);
380
381}
382
383void G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
384{
385  //G4cout << "X: " << x << ", Y: " << y << G4endl;
386  const G4int BUFSIZE = 512;
387  GLuint selectBuffer[BUFSIZE];
388  glSelectBuffer(BUFSIZE, selectBuffer);
389  glRenderMode(GL_SELECT);
390  glInitNames();
391  glPushName(0);
392  glMatrixMode(GL_PROJECTION);
393  G4double currentProjectionMatrix[16];
394  glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
395  glPushMatrix();
396  glLoadIdentity();
397  GLint viewport[4];
398  glGetIntegerv(GL_VIEWPORT, viewport);
399  // Define 5x5 pixel pick area
400  gluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
401  glMultMatrixd(currentProjectionMatrix);
402  glMatrixMode(GL_MODELVIEW);
403  DrawView();
404  GLint hits = glRenderMode(GL_RENDER);
405  if (hits < 0)
406    G4cout << "Too many hits.  Zoom in to reduce overlaps." << G4cout;
407  else if (hits > 0) {
408    //G4cout << hits << " hit(s)" << G4endl;
409    GLuint* p = selectBuffer;
410    for (GLint i = 0; i < hits; ++i) {
411      GLuint nnames = *p++;
412      *p++; //OR GLuint zmin = *p++;
413      *p++; //OR GLuint zmax = *p++;
414      //G4cout << "Hit " << i << ": " << nnames << " names"
415      //     << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
416      for (GLuint j = 0; j < nnames; ++j) {
417        GLuint name = *p++;
418        //G4cout << "Name " << j << ": PickName: " << name << G4endl;
419        std::map<GLuint, G4AttHolder*>::iterator iter =
420          fOpenGLSceneHandler.fPickMap.find(name);
421        if (iter != fOpenGLSceneHandler.fPickMap.end()) {
422          G4AttHolder* attHolder = iter->second;
423          if(attHolder && attHolder->GetAttDefs().size()) {
424            for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
425              G4cout << G4AttCheck(attHolder->GetAttValues()[i],
426                                   attHolder->GetAttDefs()[i]);
427            }
428          }
429        }
430      }
431      G4cout << G4endl;
432    }
433  }
434  glMatrixMode(GL_PROJECTION);
435  glPopMatrix();
436  glMatrixMode(GL_MODELVIEW);
437}
438
439
440
441
442GLubyte* G4OpenGLViewer::grabPixels (int inColor, unsigned int width, unsigned int height) {
443 
444  GLubyte* buffer;
445  GLint swapbytes, lsbfirst, rowlength;
446  GLint skiprows, skippixels, alignment;
447  GLenum format;
448  int size;
449
450  if (inColor) {
451    format = GL_RGB;
452    size = width*height*3;
453  } else {
454    format = GL_LUMINANCE;
455    size = width*height*1;
456  }
457
458  buffer = new GLubyte[size];
459  if (buffer == NULL)
460    return NULL;
461
462  glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
463  glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
464  glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
465
466  glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
467  glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
468  glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
469
470  glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
471  glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
472  glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
473
474  glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
475  glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
476  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
477
478  glReadBuffer(GL_FRONT);
479  glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
480
481  glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
482  glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
483  glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
484 
485  glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
486  glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
487  glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
488 
489  return buffer;
490}
491
492void G4OpenGLViewer::printEPS() {
493  bool res;
494#ifdef G4DEBUG_VIS_OGL
495  printf("G4OpenGLViewer::printEPS file:%s Vec:%d\n",getRealPrintFilename().c_str(),fVectoredPs);
496#endif
497  if (fVectoredPs) {
498    res = printVectoredEPS();
499  } else {
500    res = printNonVectoredEPS();
501  }
502  if (res == false) {
503    G4cerr << "Error while saving file... "<<getRealPrintFilename().c_str()<< G4endl;
504  } else {
505    G4cout << "File "<<getRealPrintFilename().c_str()<<" has been saved " << G4endl;
506  }
507
508  // increment index if necessary
509  if ( fPrintFilenameIndex != -1) {
510    fPrintFilenameIndex++;
511  }
512
513}
514
515bool G4OpenGLViewer::printVectoredEPS() {
516  return printGl2PS();
517}
518
519bool G4OpenGLViewer::printNonVectoredEPS () {
520
521  int width = getRealPrintSizeX();
522  int height = getRealPrintSizeY();
523
524#ifdef G4DEBUG_VIS_OGL
525  printf("G4OpenGLViewer::printNonVectoredEPS file:%s Vec:%d X:%d Y:%d col:%d\n",getRealPrintFilename().c_str(),fVectoredPs,width,height,fPrintColour);
526#endif
527  FILE* fp;
528  GLubyte* pixels;
529  GLubyte* curpix;
530  int components, pos, i;
531
532  pixels = grabPixels (fPrintColour, width, height);
533
534  if (pixels == NULL) {
535      G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
536    return false;
537  }
538  if (fPrintColour) {
539    components = 3;
540  } else {
541    components = 1;
542  }
543  std::string name = getRealPrintFilename();
544  fp = fopen (name.c_str(), "w");
545  if (fp == NULL) {
546    G4cerr << "Can't open filename " << name.c_str() << G4endl;
547    return false;
548  }
549 
550  fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
551  fprintf (fp, "%%%%Title: %s\n", name.c_str());
552  fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
553  fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
554  fprintf (fp, "%%%%EndComments\n");
555  fprintf (fp, "gsave\n");
556  fprintf (fp, "/bwproc {\n");
557  fprintf (fp, "    rgbproc\n");
558  fprintf (fp, "    dup length 3 idiv string 0 3 0 \n");
559  fprintf (fp, "    5 -1 roll {\n");
560  fprintf (fp, "    add 2 1 roll 1 sub dup 0 eq\n");
561  fprintf (fp, "    { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
562  fprintf (fp, "       3 1 roll 5 -1 roll } put 1 add 3 0 \n");
563  fprintf (fp, "    { 2 1 roll } ifelse\n");
564  fprintf (fp, "    }forall\n");
565  fprintf (fp, "    pop pop pop\n");
566  fprintf (fp, "} def\n");
567  fprintf (fp, "systemdict /colorimage known not {\n");
568  fprintf (fp, "   /colorimage {\n");
569  fprintf (fp, "       pop\n");
570  fprintf (fp, "       pop\n");
571  fprintf (fp, "       /rgbproc exch def\n");
572  fprintf (fp, "       { bwproc } image\n");
573  fprintf (fp, "   }  def\n");
574  fprintf (fp, "} if\n");
575  fprintf (fp, "/picstr %d string def\n", width * components);
576  fprintf (fp, "%d %d scale\n", width, height);
577  fprintf (fp, "%d %d %d\n", width, height, 8);
578  fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
579  fprintf (fp, "{currentfile picstr readhexstring pop}\n");
580  fprintf (fp, "false %d\n", components);
581  fprintf (fp, "colorimage\n");
582 
583  curpix = (GLubyte*) pixels;
584  pos = 0;
585  for (i = width*height*components; i>0; i--) {
586    fprintf (fp, "%02hx ", *(curpix++));
587    if (++pos >= 32) {
588      fprintf (fp, "\n");
589      pos = 0;
590    }
591  }
592  if (pos)
593    fprintf (fp, "\n");
594
595  fprintf (fp, "grestore\n");
596  fprintf (fp, "showpage\n");
597  delete pixels;
598  fclose (fp);
599
600  // Reset for next time (useful is size change)
601  //  fPrintSizeX = -1;
602  //  fPrintSizeY = -1;
603
604  return true;
605}
606
607
608bool G4OpenGLViewer::printGl2PS() {
609
610  int width = getRealPrintSizeX();
611  int height = getRealPrintSizeY();
612
613  if (!fGL2PSAction) return false;
614
615  fGL2PSAction->setFileName(getRealPrintFilename().c_str());
616  // try to resize
617  int X = fWinSize_x;
618  int Y = fWinSize_y;
619
620  fWinSize_x = width;
621  fWinSize_y = height;
622  ResizeGLView();
623  if (fGL2PSAction->enableFileWriting()) {
624
625    // By default, we choose the line width (trajectories...)
626    fGL2PSAction->setLineWidth(1);
627    // By default, we choose the point size (markers...)
628    fGL2PSAction->setPointSize(2);
629
630    DrawView ();
631    fGL2PSAction->disableFileWriting();
632  }
633
634  fWinSize_x = X;
635  fWinSize_y = Y;
636  ResizeGLView();
637
638  // Reset for next time (useful is size change)
639  //  fPrintSizeX = 0;
640  //  fPrintSizeY = 0;
641
642  return true;
643}
644
645unsigned int G4OpenGLViewer::getWinWidth() {
646  return fWinSize_x;
647}
648
649unsigned int G4OpenGLViewer::getWinHeight() {
650  return fWinSize_y;
651}
652
653G4bool G4OpenGLViewer::sizeHasChanged() {
654  return fSizeHasChanged;
655}
656
657G4int G4OpenGLViewer::getRealPrintSizeX() {
658  if (fPrintSizeX == -1) {
659    return fWinSize_x;
660  }
661  GLint dims[2];
662  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
663  if (fPrintSizeX > dims[0]){
664    return dims[0];
665  }
666  if (fPrintSizeX < -1){
667    return 0;
668  }
669  return fPrintSizeX;
670}
671
672G4int G4OpenGLViewer::getRealPrintSizeY() {
673  if (fPrintSizeY == -1) {
674    return fWinSize_y;
675  }
676  GLint dims[2];
677  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
678  if (fPrintSizeY > dims[1]){
679    return dims[1];
680  }
681  if (fPrintSizeY < -1){
682    return 0;
683  }
684  return fPrintSizeY;
685}
686
687void G4OpenGLViewer::setPrintSize(G4int X, G4int Y) {
688  fPrintSizeX = X;
689  fPrintSizeY = Y;
690}
691
692void G4OpenGLViewer::setPrintFilename(G4String name,G4bool inc) {
693  if (name != "") {
694    fPrintFilename = name;
695  } else {
696    fPrintFilename = "G4OpenGL";  // by default
697  }
698  if (inc) {
699    fPrintFilenameIndex=0;
700  } else {
701    fPrintFilenameIndex=-1;
702  }
703}
704
705std::string G4OpenGLViewer::getRealPrintFilename() {
706  std::string temp = fPrintFilename;
707  if (fPrintFilenameIndex != -1) {
708    temp += std::string("_");
709    std::ostringstream os;
710    os << fPrintFilenameIndex;
711    std::string nb_str = os.str();
712    temp += nb_str;
713  }
714  temp += ".eps";
715  return temp;
716}
717
718GLdouble G4OpenGLViewer::getSceneNearWidth()
719{
720  const G4Point3D targetPoint
721    = fSceneHandler.GetScene()->GetStandardTargetPoint()
722    + fVP.GetCurrentTargetPoint ();
723  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
724  if(radius<=0.) radius = 1.;
725  const G4double cameraDistance = fVP.GetCameraDistance (radius);
726  const GLdouble pnear   = fVP.GetNearDistance (cameraDistance, radius);
727  return 2 * fVP.GetFrontHalfHeight (pnear, radius);
728}
729
730GLdouble G4OpenGLViewer::getSceneFarWidth()
731{
732  const G4Point3D targetPoint
733    = fSceneHandler.GetScene()->GetStandardTargetPoint()
734    + fVP.GetCurrentTargetPoint ();
735  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
736  if(radius<=0.) radius = 1.;
737  const G4double cameraDistance = fVP.GetCameraDistance (radius);
738  const GLdouble pnear   = fVP.GetNearDistance (cameraDistance, radius);
739  const GLdouble pfar    = fVP.GetFarDistance  (cameraDistance, pnear, radius);
740  return 2 * fVP.GetFrontHalfHeight (pfar, radius);
741}
742
743
744GLdouble G4OpenGLViewer::getSceneDepth()
745{
746  const G4Point3D targetPoint
747    = fSceneHandler.GetScene()->GetStandardTargetPoint()
748    + fVP.GetCurrentTargetPoint ();
749  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
750  if(radius<=0.) radius = 1.;
751  const G4double cameraDistance = fVP.GetCameraDistance (radius);
752  const GLdouble pnear   = fVP.GetNearDistance (cameraDistance, radius);
753  return fVP.GetFarDistance  (cameraDistance, pnear, radius)- pnear;
754}
755
756
757
758void G4OpenGLViewer::rotateScene(G4double dx, G4double dy,G4double deltaRotation)
759{
760
761  G4Vector3D vp;
762  G4Vector3D up;
763 
764  G4Vector3D xprime;
765  G4Vector3D yprime;
766  G4Vector3D zprime;
767 
768  G4double delta_alpha;
769  G4double delta_theta;
770 
771  G4Vector3D new_vp;
772  G4Vector3D new_up;
773 
774  G4double cosalpha;
775  G4double sinalpha;
776 
777  G4Vector3D a1;
778  G4Vector3D a2;
779  G4Vector3D delta;
780  G4Vector3D viewPoint;
781
782   
783  //phi spin stuff here
784 
785  vp = fVP.GetViewpointDirection ().unit ();
786  up = fVP.GetUpVector ().unit ();
787 
788  yprime = (up.cross(vp)).unit();
789  zprime = (vp.cross(yprime)).unit();
790 
791  if (fVP.GetLightsMoveWithCamera()) {
792    delta_alpha = dy * deltaRotation;
793    delta_theta = -dx * deltaRotation;
794  } else {
795    delta_alpha = -dy * deltaRotation;
796    delta_theta = dx * deltaRotation;
797  }   
798 
799  delta_alpha *= deg;
800  delta_theta *= deg;
801 
802  new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
803 
804  // to avoid z rotation flipping
805  // to allow more than 360° rotation
806
807  const G4Point3D targetPoint
808    = fSceneHandler.GetScene()->GetStandardTargetPoint()
809    + fVP.GetCurrentTargetPoint ();
810  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
811  if(radius<=0.) radius = 1.;
812  const G4double cameraDistance = fVP.GetCameraDistance (radius);
813  const G4Point3D cameraPosition =
814    targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
815
816  if (fVP.GetLightsMoveWithCamera()) {
817    new_up = (new_vp.cross(yprime)).unit();
818    if (new_vp.z()*vp.z() <0) {
819      new_up.set(new_up.x(),-new_up.y(),new_up.z());
820    }
821  } else {
822    new_up = up;
823    if (new_vp.z()*vp.z() <0) {
824      new_up.set(new_up.x(),-new_up.y(),new_up.z());
825    }
826  }
827  fVP.SetUpVector(new_up);
828  ////////////////
829  // Rotates by fixed azimuthal angle delta_theta.
830 
831  cosalpha = new_up.dot (new_vp.unit());
832  sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
833  yprime = (new_up.cross (new_vp.unit())).unit ();
834  xprime = yprime.cross (new_up);
835  // Projection of vp on plane perpendicular to up...
836  a1 = sinalpha * xprime;
837  // Required new projection...
838  a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
839  // Required Increment vector...
840  delta = a2 - a1;
841  // So new viewpoint is...
842  viewPoint = new_vp.unit() + delta;
843 
844  fVP.SetViewAndLights (viewPoint);
845}
846
847#endif
Note: See TracBrowser for help on using the repository browser.