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

Last change on this file since 1349 was 1348, checked in by garnier, 15 years ago

update

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