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

Last change on this file since 1327 was 1327, checked in by garnier, 14 years ago

bug fix ?

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