Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4OpenGLViewer.cc
Go to the documentation of this file.
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$
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"
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// GL2PS
54#include "Geant4_gl2ps.h"
55
56#include <sstream>
57
58G4int G4OpenGLViewer::fPrintSizeX = -1;
59G4int G4OpenGLViewer::fPrintSizeY = -1;
60G4String G4OpenGLViewer::fPrintFilename = "G4OpenGL";
61int G4OpenGLViewer::fPrintFilenameIndex = 0;
62
63G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
64G4VViewer (scene, -1),
65fPrintColour (true),
66fVectoredPs (true),
67fOpenGLSceneHandler(scene),
68background (G4Colour(0.,0.,0.)),
69transparency_enabled (true),
70antialiasing_enabled (false),
71haloing_enabled (false),
72fStartTime(-DBL_MAX),
73fEndTime(DBL_MAX),
74fFadeFactor(0.),
75fDisplayHeadTime(false),
76fDisplayHeadTimeX(-0.9),
77fDisplayHeadTimeY(-0.9),
78fDisplayHeadTimeSize(24.),
79fDisplayHeadTimeRed(0.),
80fDisplayHeadTimeGreen(1.),
81fDisplayHeadTimeBlue(1.),
82fDisplayLightFront(false),
83fDisplayLightFrontX(0.),
84fDisplayLightFrontY(0.),
85fDisplayLightFrontZ(0.),
86fDisplayLightFrontT(0.),
87fDisplayLightFrontRed(0.),
88fDisplayLightFrontGreen(1.),
89fDisplayLightFrontBlue(0.),
90fRot_sens(1.),
91fPan_sens(0.01),
92fWinSize_x(0),
93fWinSize_y(0),
94fPointSize (0),
95fSizeHasChanged(0),
96fGl2psDefaultLineWith(1),
97fGl2psDefaultPointSize(2)
98{
99#ifdef G4DEBUG_VIS_OGL
100 printf("G4OpenGLViewer:: Creation\n");
101#endif
102 // Make changes to view parameters for OpenGL...
103 fVP.SetAutoRefresh(true);
104 fDefaultVP.SetAutoRefresh(true);
105
106 fGL2PSAction = new G4OpenGL2PSAction();
107
108 // glClearColor (0.0, 0.0, 0.0, 0.0);
109 // glClearDepth (1.0);
110 // glDisable (GL_BLEND);
111 // glDisable (GL_LINE_SMOOTH);
112 // glDisable (GL_POLYGON_SMOOTH);
113
114}
115
116G4OpenGLViewer::~G4OpenGLViewer ()
117{
118 delete fGL2PSAction;
119}
120
121void G4OpenGLViewer::InitializeGLView ()
122{
123#ifdef G4DEBUG_VIS_OGL
124 printf("G4OpenGLViewer::InitializeGLView\n");
125#endif
126
127 fWinSize_x = fVP.GetWindowSizeHintX();
128 fWinSize_y = fVP.GetWindowSizeHintY();
129
130 glClearColor (0.0, 0.0, 0.0, 0.0);
131 glClearDepth (1.0);
132 glDisable (GL_LINE_SMOOTH);
133 glDisable (GL_POLYGON_SMOOTH);
134
135// clear the buffers and window?
136 ClearView ();
137 FinishView ();
138
139 glDepthFunc (GL_LEQUAL);
140 glDepthMask (GL_TRUE);
141
142 glEnable (GL_BLEND);
143 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
144
145#ifdef G4DEBUG_VIS_OGL
146 printf("G4OpenGLViewer::InitializeGLView END\n");
147#endif
148}
149
150void G4OpenGLViewer::ClearView () {
151#ifdef G4DEBUG_VIS_OGL
152 printf("G4OpenGLViewer::ClearView\n");
153#endif
154 glClearColor (background.GetRed(),
155 background.GetGreen(),
156 background.GetBlue(),
157 1.);
158 glClearDepth (1.0);
159 //Below line does not compile with Mesa includes.
160 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
161 glClear (GL_COLOR_BUFFER_BIT);
162 glClear (GL_DEPTH_BUFFER_BIT);
163 glClear (GL_STENCIL_BUFFER_BIT);
164#ifdef G4DEBUG_VIS_OGL
165 printf("G4OpenGLViewer::ClearView flush\n");
166#endif
167 glFlush ();
168}
169
170
171void G4OpenGLViewer::ResizeWindow(unsigned int aWidth, unsigned int aHeight) {
172 if ((fWinSize_x != aWidth) || (fWinSize_y != aHeight)) {
173 fWinSize_x = aWidth;
174 fWinSize_y = aHeight;
175 fSizeHasChanged = true;
176 } else {
177 fSizeHasChanged = false;
178 }
179}
180
181/**
182 * Set the viewport of the scene
183 * MAXIMUM SIZE is :
184 * GLint dims[2];
185 * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
186 */
187void G4OpenGLViewer::ResizeGLView()
188{
189#ifdef G4DEBUG_VIS_OGL
190 printf("G4OpenGLViewer::ResizeGLView %d %d %#lx\n",fWinSize_x,fWinSize_y,(unsigned long)this);
191#endif
192 // Check size
193 GLint dims[2];
194 dims[0] = 0;
195 dims[1] = 0;
196
197 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
198
199 if ((dims[0] !=0 ) && (dims[1] !=0)) {
200
201 if (fWinSize_x > (unsigned)dims[0]) {
202 G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<fWinSize_x <<" is resize to "<< dims[0] << G4endl;
203 fWinSize_x = dims[0];
204 }
205 if (fWinSize_y > (unsigned)dims[1]) {
206 G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<fWinSize_y <<" is resize to "<< dims[1] << G4endl;
207 fWinSize_y = dims[1];
208 }
209 }
210
211 glViewport(0, 0, fWinSize_x,fWinSize_y);
212
213
214}
215
216
217void G4OpenGLViewer::SetView () {
218
219 if (!fSceneHandler.GetScene()) {
220 return;
221 }
222 // Calculates view representation based on extent of object being
223 // viewed and (initial) viewpoint. (Note: it can change later due
224 // to user interaction via visualization system's GUI.)
225
226 // Lighting.
227 GLfloat lightPosition [4];
228 lightPosition [0] = fVP.GetActualLightpointDirection().x();
229 lightPosition [1] = fVP.GetActualLightpointDirection().y();
230 lightPosition [2] = fVP.GetActualLightpointDirection().z();
231 lightPosition [3] = 0.;
232 // Light position is "true" light direction, so must come after gluLookAt.
233 GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.};
234 GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.};
235 glEnable (GL_LIGHT0);
236 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
237 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
238
239 G4double ratioX = 1;
240 G4double ratioY = 1;
241 if (fWinSize_y > fWinSize_x) {
242 ratioX = ((G4double)fWinSize_y) / ((G4double)fWinSize_x);
243 }
244 if (fWinSize_x > fWinSize_y) {
245 ratioY = ((G4double)fWinSize_x) / ((G4double)fWinSize_y);
246 }
247
248 // Get radius of scene, etc.
249 // Note that this procedure properly takes into account zoom, dolly and pan.
250 const G4Point3D targetPoint
251 = fSceneHandler.GetScene()->GetStandardTargetPoint()
252 + fVP.GetCurrentTargetPoint ();
253 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
254 if(radius<=0.) radius = 1.;
255 const G4double cameraDistance = fVP.GetCameraDistance (radius);
256 const G4Point3D cameraPosition =
257 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
258 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
259 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
260 const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius) * ratioY;
261 const GLdouble left = -right;
262 const GLdouble top = fVP.GetFrontHalfHeight (pnear, radius) * ratioX;
263 const GLdouble bottom = -top;
264
265 // FIXME
266 ResizeGLView();
267 //SHOULD SetWindowsSizeHint()...
268
269 glMatrixMode (GL_PROJECTION); // set up Frustum.
270 glLoadIdentity();
271
272 const G4Vector3D scaleFactor = fVP.GetScaleFactor();
273 glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
274
275 if (fVP.GetFieldHalfAngle() == 0.) {
276 glOrtho (left, right, bottom, top, pnear, pfar);
277 }
278 else {
279 glFrustum (left, right, bottom, top, pnear, pfar);
280 }
281
282 glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
283 glLoadIdentity();
284
285 const G4Normal3D& upVector = fVP.GetUpVector ();
286 G4Point3D gltarget;
287 if (cameraDistance > 1.e-6 * radius) {
288 gltarget = targetPoint;
289 }
290 else {
291 gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
292 }
293
294 const G4Point3D& pCamera = cameraPosition; // An alias for brevity.
295 gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
296 gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
297 upVector.x(), upVector.y(), upVector.z()); // Up vector.
298
299 // Light position is "true" light direction, so must come after gluLookAt.
300 glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
301
302 // OpenGL no longer seems to reconstruct clipped edges, so, when the
303 // BooleanProcessor is up to it, abandon this and use generic
304 // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron. Also,
305 // force kernel visit on change of clipping plane in
306 // G4OpenGLStoredViewer::CompareForKernelVisit.
307 //if (fVP.IsSection () ) { // pair of back to back clip planes.
308 if (false) { // pair of back to back clip planes.
309 const G4Plane3D& sp = fVP.GetSectionPlane ();
310 double sArray[4];
311 sArray[0] = sp.a();
312 sArray[1] = sp.b();
313 sArray[2] = sp.c();
314 sArray[3] = sp.d() + radius * 1.e-05;
315 glClipPlane (GL_CLIP_PLANE0, sArray);
316 glEnable (GL_CLIP_PLANE0);
317 sArray[0] = -sp.a();
318 sArray[1] = -sp.b();
319 sArray[2] = -sp.c();
320 sArray[3] = -sp.d() + radius * 1.e-05;
321 glClipPlane (GL_CLIP_PLANE1, sArray);
322 glEnable (GL_CLIP_PLANE1);
323 } else {
324 glDisable (GL_CLIP_PLANE0);
325 glDisable (GL_CLIP_PLANE1);
326 }
327
328 // What we call intersection of cutaways is easy in OpenGL. You
329 // just keep cutting. Unions are more tricky - you have to have
330 // multiple passes and this is handled in
331 // G4OpenGLImmediate/StoredViewer::ProcessView.
332 const G4Planes& cutaways = fVP.GetCutawayPlanes();
333 size_t nPlanes = cutaways.size();
334 if (fVP.IsCutaway() &&
335 fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
336 nPlanes > 0) {
337 double a[4];
338 a[0] = cutaways[0].a();
339 a[1] = cutaways[0].b();
340 a[2] = cutaways[0].c();
341 a[3] = cutaways[0].d();
342 glClipPlane (GL_CLIP_PLANE2, a);
343 glEnable (GL_CLIP_PLANE2);
344 if (nPlanes > 1) {
345 a[0] = cutaways[1].a();
346 a[1] = cutaways[1].b();
347 a[2] = cutaways[1].c();
348 a[3] = cutaways[1].d();
349 glClipPlane (GL_CLIP_PLANE3, a);
350 glEnable (GL_CLIP_PLANE3);
351 }
352 if (nPlanes > 2) {
353 a[0] = cutaways[2].a();
354 a[1] = cutaways[2].b();
355 a[2] = cutaways[2].c();
356 a[3] = cutaways[2].d();
357 glClipPlane (GL_CLIP_PLANE4, a);
358 glEnable (GL_CLIP_PLANE4);
359 }
360 } else {
361 glDisable (GL_CLIP_PLANE2);
362 glDisable (GL_CLIP_PLANE3);
363 glDisable (GL_CLIP_PLANE4);
364 }
365
366 // Background.
367 background = fVP.GetBackgroundColour ();
368
369}
370
371
372
373void G4OpenGLViewer::ResetView () {
375 fRot_sens = 1;
376 fPan_sens = 0.01;
377}
378
379
380void G4OpenGLViewer::HaloingFirstPass () {
381
382 //To perform haloing, first Draw all information to the depth buffer
383 //alone, using a chunky line width, and then Draw all info again, to
384 //the colour buffer, setting a thinner line width an the depth testing
385 //function to less than or equal, so if two lines cross, the one
386 //passing behind the other will not pass the depth test, and so not
387 //get rendered either side of the infront line for a short distance.
388
389 //First, disable writing to the colo(u)r buffer...
390 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
391
392 //Now enable writing to the depth buffer...
393 glDepthMask (GL_TRUE);
394 glDepthFunc (GL_LESS);
395 glClearDepth (1.0);
396
397 //Finally, set the line width to something wide...
398 ChangeLineWidth(3.0);
399
400}
401
402void G4OpenGLViewer::HaloingSecondPass () {
403
404 //And finally, turn the colour buffer back on with a sesible line width...
405 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
406 glDepthFunc (GL_LEQUAL);
407 ChangeLineWidth(1.0);
408
409}
410
411void G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
412{
413 //G4cout << "X: " << x << ", Y: " << y << G4endl;
414 const G4int BUFSIZE = 512;
415 GLuint selectBuffer[BUFSIZE];
416 glSelectBuffer(BUFSIZE, selectBuffer);
417 glRenderMode(GL_SELECT);
418 glInitNames();
419 glPushName(0);
420 glMatrixMode(GL_PROJECTION);
421 G4double currentProjectionMatrix[16];
422 glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
423 glPushMatrix();
424 glLoadIdentity();
425 GLint viewport[4];
426 glGetIntegerv(GL_VIEWPORT, viewport);
427 // Define 5x5 pixel pick area
428 gluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
429 glMultMatrixd(currentProjectionMatrix);
430 glMatrixMode(GL_MODELVIEW);
431 DrawView();
432 GLint hits = glRenderMode(GL_RENDER);
433 if (hits < 0)
434 G4cout << "Too many hits. Zoom in to reduce overlaps." << G4endl;
435 else if (hits > 0) {
436 G4cout << hits << " hit(s)" << G4endl;
437 GLuint* p = selectBuffer;
438 for (GLint i = 0; i < hits; ++i) {
439 GLuint nnames = *p++;
440 // This bit of debug code or...
441 //GLuint zmin = *p++;
442 //GLuint zmax = *p++;
443 //G4cout << "Hit " << i << ": " << nnames << " names"
444 // << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
445 // ...just increment the pointer
446 p++;
447 p++;
448 for (GLuint j = 0; j < nnames; ++j) {
449 GLuint name = *p++;
450 G4cout << "Hit: " << i
451 << ", Sub-hit: " << j
452 << ", PickName: " << name << G4endl;
453 std::map<GLuint, G4AttHolder*>::iterator iter =
454 fOpenGLSceneHandler.fPickMap.find(name);
455 if (iter != fOpenGLSceneHandler.fPickMap.end()) {
456 G4AttHolder* attHolder = iter->second;
457 if(attHolder && attHolder->GetAttDefs().size()) {
458 for (size_t iAtt = 0;
459 iAtt < attHolder->GetAttDefs().size(); ++iAtt) {
460 G4cout << G4AttCheck(attHolder->GetAttValues()[iAtt],
461 attHolder->GetAttDefs()[iAtt]);
462 }
463 }
464 }
465 }
466 G4cout << G4endl;
467 }
468 }
469 glMatrixMode(GL_PROJECTION);
470 glPopMatrix();
471 glMatrixMode(GL_MODELVIEW);
472}
473
474
475
476
477GLubyte* G4OpenGLViewer::grabPixels (int inColor, unsigned int width, unsigned int height) {
478
479 GLubyte* buffer;
480 GLint swapbytes, lsbfirst, rowlength;
481 GLint skiprows, skippixels, alignment;
482 GLenum format;
483 int size;
484
485 if (inColor) {
486 format = GL_RGB;
487 size = width*height*3;
488 } else {
489 format = GL_LUMINANCE;
490 size = width*height*1;
491 }
492
493 buffer = new GLubyte[size];
494 if (buffer == NULL)
495 return NULL;
496
497 glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
498 glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
499 glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
500
501 glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
502 glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
503 glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
504
505 glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
506 glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
507 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
508
509 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
510 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
511 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
512
513 glReadBuffer(GL_FRONT);
514 glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
515
516 glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
517 glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
518 glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
519
520 glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
521 glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
522 glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
523
524 return buffer;
525}
526
527void G4OpenGLViewer::printEPS() {
528 bool res;
529#ifdef G4DEBUG_VIS_OGL
530 printf("G4OpenGLViewer::printEPS file:%s Vec:%d Name:%s\n",getRealPrintFilename().c_str(),fVectoredPs,GetName().c_str());
531#endif
532
533 // Change the LC_NUMERIC value in order to have "." separtor and not ","
534 // This case is only useful for French, Canadien...
535 size_t len = strlen(setlocale(LC_NUMERIC,NULL));
536 char* oldLocale = (char*)(malloc(len+1));
537 if(oldLocale!=NULL) strncpy(oldLocale,setlocale(LC_NUMERIC,NULL),len);
538 setlocale(LC_NUMERIC,"C");
539
540 if (fVectoredPs) {
541 res = printVectoredEPS();
542 } else {
543 res = printNonVectoredEPS();
544 }
545
546 // restore the local
547 if (oldLocale) {
548 setlocale(LC_NUMERIC,oldLocale);
549 free(oldLocale);
550 }
551
552 if (res == false) {
553 G4cerr << "Error while saving file... "<<getRealPrintFilename().c_str()<< G4endl;
554 } else {
555 G4cout << "File "<<getRealPrintFilename().c_str()<<" has been saved " << G4endl;
556 }
557
558 // increment index if necessary
559 if ( fPrintFilenameIndex != -1) {
560 fPrintFilenameIndex++;
561 }
562
563#ifdef G4DEBUG_VIS_OGL
564 printf("G4OpenGLViewer::printEPS END\n");
565#endif
566}
567
568bool G4OpenGLViewer::printVectoredEPS() {
569 return printGl2PS();
570}
571
572bool G4OpenGLViewer::printNonVectoredEPS () {
573
574 int width = getRealPrintSizeX();
575 int height = getRealPrintSizeY();
576
577#ifdef G4DEBUG_VIS_OGL
578 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);
579#endif
580 FILE* fp;
581 GLubyte* pixels;
582 GLubyte* curpix;
583 int components, pos, i;
584
585 pixels = grabPixels (fPrintColour, width, height);
586
587 if (pixels == NULL) {
588 G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
589 return false;
590 }
591 if (fPrintColour) {
592 components = 3;
593 } else {
594 components = 1;
595 }
596 std::string name = getRealPrintFilename();
597 fp = fopen (name.c_str(), "w");
598 if (fp == NULL) {
599 G4cerr << "Can't open filename " << name.c_str() << G4endl;
600 return false;
601 }
602
603 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
604 fprintf (fp, "%%%%Title: %s\n", name.c_str());
605 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
606 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
607 fprintf (fp, "%%%%EndComments\n");
608 fprintf (fp, "gsave\n");
609 fprintf (fp, "/bwproc {\n");
610 fprintf (fp, " rgbproc\n");
611 fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
612 fprintf (fp, " 5 -1 roll {\n");
613 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
614 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
615 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
616 fprintf (fp, " { 2 1 roll } ifelse\n");
617 fprintf (fp, " }forall\n");
618 fprintf (fp, " pop pop pop\n");
619 fprintf (fp, "} def\n");
620 fprintf (fp, "systemdict /colorimage known not {\n");
621 fprintf (fp, " /colorimage {\n");
622 fprintf (fp, " pop\n");
623 fprintf (fp, " pop\n");
624 fprintf (fp, " /rgbproc exch def\n");
625 fprintf (fp, " { bwproc } image\n");
626 fprintf (fp, " } def\n");
627 fprintf (fp, "} if\n");
628 fprintf (fp, "/picstr %d string def\n", width * components);
629 fprintf (fp, "%d %d scale\n", width, height);
630 fprintf (fp, "%d %d %d\n", width, height, 8);
631 fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
632 fprintf (fp, "{currentfile picstr readhexstring pop}\n");
633 fprintf (fp, "false %d\n", components);
634 fprintf (fp, "colorimage\n");
635
636 curpix = (GLubyte*) pixels;
637 pos = 0;
638 for (i = width*height*components; i>0; i--) {
639 fprintf (fp, "%02hx ", (unsigned short)(*(curpix++)));
640 if (++pos >= 32) {
641 fprintf (fp, "\n");
642 pos = 0;
643 }
644 }
645 if (pos)
646 fprintf (fp, "\n");
647
648 fprintf (fp, "grestore\n");
649 fprintf (fp, "showpage\n");
650 delete [] pixels;
651 fclose (fp);
652
653 // Reset for next time (useful is size change)
654 // fPrintSizeX = -1;
655 // fPrintSizeY = -1;
656
657 return true;
658}
659
660/** Return if gl2ps is currently writing
661 */
662bool G4OpenGLViewer::isGl2psWriting() {
663
664 if (!fGL2PSAction) return false;
665 if (fGL2PSAction->fileWritingEnabled()) {
666 return true;
667 }
668 return false;
669}
670
671
672/* Draw Gl2Ps text if needed
673 */
674void G4OpenGLViewer::DrawText(const G4Text& g4text)
675{
676 // gl2ps or GL window ?
677 if (isGl2psWriting()) {
678
680 G4double size = fSceneHandler.GetMarkerSize(g4text,sizeType);
681 G4Point3D position = g4text.GetPosition();
682
683 G4String textString = g4text.GetText();
684 const char* textCString = textString.c_str();
685
686 glRasterPos3d(position.x(),position.y(),position.z());
687 GLint align = GL2PS_TEXT_B;
688
689 switch (g4text.GetLayout()) {
690 case G4Text::left: align = GL2PS_TEXT_BL; break;
691 case G4Text::centre: align = GL2PS_TEXT_B; break;
692 case G4Text::right: align = GL2PS_TEXT_BR;
693 }
694
695 gl2psTextOpt(textCString,"Times-Roman",GLshort(size),align,0);
696
697 } else {
698
699 static G4int callCount = 0;
700 ++callCount;
701 //if (callCount <= 10 || callCount%100 == 0) {
702 if (callCount <= 1) {
703 G4cout <<
704 "G4OpenGLViewer::DrawText: Not implemented for \""
705 << fName <<
706 "\"\n Called with "
707 << g4text
708 << G4endl;
709 }
710 }
711}
712
713/** Change PointSize on gl2ps if needed
714 */
715void G4OpenGLViewer::ChangePointSize(G4double size) {
716
717 if (isGl2psWriting()) {
718 fGL2PSAction->setPointSize(int(size));
719 } else {
720 glPointSize (size);
721 }
722}
723
724
725/** Change LineSize on gl2ps if needed
726 */
727void G4OpenGLViewer::ChangeLineWidth(G4double width) {
728
729 if (isGl2psWriting()) {
730 fGL2PSAction->setLineWidth(int(width));
731 } else {
732 glLineWidth (width);
733 }
734}
735
736
737bool G4OpenGLViewer::printGl2PS() {
738
739 int width = getRealPrintSizeX();
740 int height = getRealPrintSizeY();
741
742 if (!fGL2PSAction) return false;
743
744 fGL2PSAction->setFileName(getRealPrintFilename().c_str());
745 // try to resize
746 int X = fWinSize_x;
747 int Y = fWinSize_y;
748
749 fWinSize_x = width;
750 fWinSize_y = height;
751 // Laurent G. 16/03/10 : Not the good way to do.
752 // We should draw in a new offscreen context instead of
753 // resizing and drawing in current window...
754 // This should be solve when we will do an offscreen method
755 // to render OpenGL
756 // See :
757 // http://developer.apple.com/Mac/library/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_offscreen/opengl_offscreen.html
758 // http://www.songho.ca/opengl/gl_fbo.html
759
760 ResizeGLView();
761 bool extendBuffer = true;
762 bool endWriteAction = false;
763 bool beginWriteAction = true;
764 while ((extendBuffer) && (! endWriteAction)) {
765
766 beginWriteAction = fGL2PSAction->enableFileWriting();
767 if (beginWriteAction) {
768
769 // Set the viewport
770 // fGL2PSAction->setViewport(0, 0, getRealPrintSizeX(),getRealPrintSizeY());
771 // By default, we choose the line width (trajectories...)
772 fGL2PSAction->setLineWidth(fGl2psDefaultLineWith);
773 // By default, we choose the point size (markers...)
774 fGL2PSAction->setPointSize(fGl2psDefaultPointSize);
775
776 DrawView ();
777 endWriteAction = fGL2PSAction->disableFileWriting();
778 }
779 if ((! endWriteAction) || (! beginWriteAction)) {
780 extendBuffer = fGL2PSAction->extendBufferSize();
781 }
782 }
783 fGL2PSAction->resetBufferSizeParameters();
784
785 if (!extendBuffer ) {
786 G4cerr << "gl2ps buffer size is not big enough to print this geometry. Thy to extend it. No output produced"<< G4endl;
787 }
788 if (!beginWriteAction ) {
789 G4cerr << "Error while writing in the file "<<getRealPrintFilename().c_str()<<". Check read/write access No output produced" << G4endl;
790 }
791 if (!endWriteAction ) {
792 G4cerr << "gl2ps error. No output produced" << G4endl;
793 }
794 fWinSize_x = X;
795 fWinSize_y = Y;
796
797 // Reset for next time (useful is size change)
798 // fPrintSizeX = 0;
799 // fPrintSizeY = 0;
800
801 return true;
802}
803
804unsigned int G4OpenGLViewer::getWinWidth() {
805 return fWinSize_x;
806}
807
808unsigned int G4OpenGLViewer::getWinHeight() {
809 return fWinSize_y;
810}
811
812G4bool G4OpenGLViewer::sizeHasChanged() {
813 return fSizeHasChanged;
814}
815
816G4int G4OpenGLViewer::getRealPrintSizeX() {
817 if (fPrintSizeX == -1) {
818 return fWinSize_x;
819 }
820 GLint dims[2];
821 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
822
823 // L.Garnier 01-2010: Some problems with mac 10.6
824 if ((dims[0] !=0 ) && (dims[1] !=0)) {
825 if (fPrintSizeX > dims[0]){
826 return dims[0];
827 }
828 }
829 if (fPrintSizeX < -1){
830 return 0;
831 }
832 return fPrintSizeX;
833}
834
835G4int G4OpenGLViewer::getRealPrintSizeY() {
836 if (fPrintSizeY == -1) {
837 return fWinSize_y;
838 }
839 GLint dims[2];
840 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
841
842 // L.Garnier 01-2010: Some problems with mac 10.6
843 if ((dims[0] !=0 ) && (dims[1] !=0)) {
844 if (fPrintSizeY > dims[1]){
845 return dims[1];
846 }
847 }
848 if (fPrintSizeY < -1){
849 return 0;
850 }
851 return fPrintSizeY;
852}
853
854void G4OpenGLViewer::setPrintSize(G4int X, G4int Y) {
855 fPrintSizeX = X;
856 fPrintSizeY = Y;
857}
858
859void G4OpenGLViewer::setPrintFilename(G4String name,G4bool inc) {
860 if (name != "") {
861 fPrintFilename = name;
862 } else {
863 fPrintFilename = "G4OpenGL"; // by default
864 }
865 if (inc) {
866 fPrintFilenameIndex=0;
867 } else {
868 fPrintFilenameIndex=-1;
869 }
870}
871
872std::string G4OpenGLViewer::getRealPrintFilename() {
873 std::string temp = fPrintFilename;
874 if (fPrintFilenameIndex != -1) {
875 temp += std::string("_");
876 std::ostringstream os;
877 os << fPrintFilenameIndex;
878 std::string nb_str = os.str();
879 temp += nb_str;
880 }
881 temp += ".eps";
882 return temp;
883}
884
885GLdouble G4OpenGLViewer::getSceneNearWidth()
886{
887 if (!fSceneHandler.GetScene()) {
888 return 0;
889 }
890 const G4Point3D targetPoint
891 = fSceneHandler.GetScene()->GetStandardTargetPoint()
892 + fVP.GetCurrentTargetPoint ();
893 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
894 if(radius<=0.) radius = 1.;
895 const G4double cameraDistance = fVP.GetCameraDistance (radius);
896 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
897 return 2 * fVP.GetFrontHalfHeight (pnear, radius);
898}
899
900GLdouble G4OpenGLViewer::getSceneFarWidth()
901{
902 if (!fSceneHandler.GetScene()) {
903 return 0;
904 }
905 const G4Point3D targetPoint
906 = fSceneHandler.GetScene()->GetStandardTargetPoint()
907 + fVP.GetCurrentTargetPoint ();
908 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
909 if(radius<=0.) radius = 1.;
910 const G4double cameraDistance = fVP.GetCameraDistance (radius);
911 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
912 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
913 return 2 * fVP.GetFrontHalfHeight (pfar, radius);
914}
915
916
917GLdouble G4OpenGLViewer::getSceneDepth()
918{
919 if (!fSceneHandler.GetScene()) {
920 return 0;
921 }
922 const G4Point3D targetPoint
923 = fSceneHandler.GetScene()->GetStandardTargetPoint()
924 + fVP.GetCurrentTargetPoint ();
925 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
926 if(radius<=0.) radius = 1.;
927 const G4double cameraDistance = fVP.GetCameraDistance (radius);
928 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
929 return fVP.GetFarDistance (cameraDistance, pnear, radius)- pnear;
930}
931
932
933
934void G4OpenGLViewer::rotateScene(G4double dx, G4double dy)
935{
936 if (fVP.GetRotationStyle() == G4ViewParameters::freeRotation) {
937 rotateSceneInViewDirection(dx,dy);
938 } else {
939 if( dx != 0) {
940 rotateSceneThetaPhi(dx,0);
941 }
942 if( dy != 0) {
943 rotateSceneThetaPhi(0,dy);
944 }
945 }
946}
947
948
949void G4OpenGLViewer::rotateSceneToggle(G4double dx, G4double dy)
950{
951 if (fVP.GetRotationStyle() != G4ViewParameters::freeRotation) {
952 rotateSceneInViewDirection(dx,dy);
953 } else {
954 if( dx != 0) {
955 rotateSceneThetaPhi(dx,0);
956 }
957 if( dy != 0) {
958 rotateSceneThetaPhi(0,dy);
959 }
960 }
961}
962
963void G4OpenGLViewer::rotateSceneThetaPhi(G4double dx, G4double dy)
964{
965 if (!fSceneHandler.GetScene()) {
966 return;
967 }
968
969 G4Vector3D vp;
970 G4Vector3D up;
971
972 G4Vector3D xprime;
973 G4Vector3D yprime;
974 G4Vector3D zprime;
975
976 G4double delta_alpha;
977 G4double delta_theta;
978
979 G4Vector3D new_vp;
980 G4Vector3D new_up;
981
982 G4double cosalpha;
983 G4double sinalpha;
984
985 G4Vector3D a1;
986 G4Vector3D a2;
987 G4Vector3D delta;
988 G4Vector3D viewPoint;
989
990
991 //phi spin stuff here
992
993 vp = fVP.GetViewpointDirection ().unit ();
994 up = fVP.GetUpVector ().unit ();
995
996 yprime = (up.cross(vp)).unit();
997 zprime = (vp.cross(yprime)).unit();
998
999 if (fVP.GetLightsMoveWithCamera()) {
1000 delta_alpha = dy * fRot_sens;
1001 delta_theta = -dx * fRot_sens;
1002 } else {
1003 delta_alpha = -dy * fRot_sens;
1004 delta_theta = dx * fRot_sens;
1005 }
1006
1007 delta_alpha *= deg;
1008 delta_theta *= deg;
1009
1010 new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1011
1012 // to avoid z rotation flipping
1013 // to allow more than 360� rotation
1014
1015 if (fVP.GetLightsMoveWithCamera()) {
1016 new_up = (new_vp.cross(yprime)).unit();
1017 if (new_vp.z()*vp.z() <0) {
1018 new_up.set(new_up.x(),-new_up.y(),new_up.z());
1019 }
1020 } else {
1021 new_up = up;
1022 if (new_vp.z()*vp.z() <0) {
1023 new_up.set(new_up.x(),-new_up.y(),new_up.z());
1024 }
1025 }
1026 fVP.SetUpVector(new_up);
1027 ////////////////
1028 // Rotates by fixed azimuthal angle delta_theta.
1029
1030 cosalpha = new_up.dot (new_vp.unit());
1031 sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1032 yprime = (new_up.cross (new_vp.unit())).unit ();
1033 xprime = yprime.cross (new_up);
1034 // Projection of vp on plane perpendicular to up...
1035 a1 = sinalpha * xprime;
1036 // Required new projection...
1037 a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1038 // Required Increment vector...
1039 delta = a2 - a1;
1040 // So new viewpoint is...
1041 viewPoint = new_vp.unit() + delta;
1042
1043 fVP.SetViewAndLights (viewPoint);
1044}
1045
1046
1047void G4OpenGLViewer::rotateSceneInViewDirection(G4double dx, G4double dy)
1048{
1049 if (!fSceneHandler.GetScene()) {
1050 return;
1051 }
1052
1053 G4Vector3D vp;
1054 G4Vector3D up;
1055
1056 G4Vector3D xprime;
1057 G4Vector3D yprime;
1058 G4Vector3D zprime;
1059
1060 G4Vector3D new_vp;
1061 G4Vector3D new_up;
1062
1063 G4Vector3D a1;
1064 G4Vector3D a2;
1065 G4Vector3D delta;
1066 G4Vector3D viewPoint;
1067
1068 dx = dx/100;
1069 dy = dy/100;
1070
1071 //phi spin stuff here
1072
1073#ifdef G4DEBUG_VIS_OGL
1074 printf("G4OpenGLViewer::rotateScene dx:%f dy:%f delta:%f\n",dx,dy, fRot_sens);
1075#endif
1076
1077 vp = fVP.GetViewpointDirection ().unit();
1078 up = fVP.GetUpVector ().unit();
1079
1080 G4Vector3D zPrimeVector = G4Vector3D(up.y()*vp.z()-up.z()*vp.y(),
1081 up.z()*vp.x()-up.x()*vp.z(),
1082 up.x()*vp.y()-up.y()*vp.x());
1083
1084 viewPoint = vp/fRot_sens + (zPrimeVector*dx - up*dy) ;
1085 new_up = G4Vector3D(viewPoint.y()*zPrimeVector.z()-viewPoint.z()*zPrimeVector.y(),
1086 viewPoint.z()*zPrimeVector.x()-viewPoint.x()*zPrimeVector.z(),
1087 viewPoint.x()*zPrimeVector.y()-viewPoint.y()*zPrimeVector.x());
1088
1089 G4Vector3D new_upUnit = new_up.unit();
1090
1091
1092
1093 fVP.SetUpVector(new_upUnit);
1094 fVP.SetViewAndLights (viewPoint);
1095}
1096
1097
1098#endif
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
std::vector< G4Plane3D > G4Planes
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
#define gl2psTextOpt
Definition: Geant4_gl2ps.h:44
const std::vector< const std::vector< G4AttValue > * > & GetAttValues() const
Definition: G4AttHolder.hh:60
const std::vector< const std::map< G4String, G4AttDef > * > & GetAttDefs() const
Definition: G4AttHolder.hh:62
Definition: G4Text.hh:73
Layout GetLayout() const
G4String GetText() const
@ centre
Definition: G4Text.hh:77
@ right
Definition: G4Text.hh:77
@ left
Definition: G4Text.hh:77
G4Point3D GetPosition() const
virtual void ResetView()
BasicVector3D< T > cross(const BasicVector3D< T > &v) const
BasicVector3D< T > unit() const
void set(T x1, T y1, T z1)
T dot(const BasicVector3D< T > &v) const
#define GL2PS_TEXT_BL
Definition: gl2ps.h:176
#define GL2PS_TEXT_BR
Definition: gl2ps.h:177
#define GL2PS_TEXT_B
Definition: gl2ps.h:175
#define DBL_MAX
Definition: templates.hh:83
#define buffer
Definition: xmlparse.cc:611