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

Last change on this file since 1237 was 1233, checked in by garnier, 15 years ago

debug visu

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