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

Last change on this file since 1331 was 1327, checked in by garnier, 15 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.