Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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//
28//
29// Andrew Walkden 27th March 1996
30// OpenGL view - opens window, hard copy, etc.
31
32#include "G4ios.hh"
34#include "G4OpenGLViewer.hh"
37
38#include "G4gl2ps.hh"
39#define GL2PS_TEXT_B TOOLS_GL2PS_TEXT_B
40#define GL2PS_TEXT_BL TOOLS_GL2PS_TEXT_BL
41#define GL2PS_TEXT_BR TOOLS_GL2PS_TEXT_BR
42
43#include "G4Scene.hh"
44#include "G4VisExtent.hh"
45#include "G4LogicalVolume.hh"
46#include "G4VSolid.hh"
47#include "G4Point3D.hh"
48#include "G4Normal3D.hh"
49#include "G4Plane3D.hh"
50#include "G4AttHolder.hh"
51#include "G4AttCheck.hh"
52#include "G4Text.hh"
53
54#include <sstream>
55#include <string>
56#include <iomanip>
57
59G4VViewer (scene, -1),
60fPrintColour (true),
61fVectoredPs (true),
63background (G4Colour(0.,0.,0.)),
66haloing_enabled (false),
67fRot_sens(1.),
68fPan_sens(0.01),
69fWinSize_x(0),
70fWinSize_y(0),
74fPrintSizeX(-1),
75fPrintSizeY(-1),
76fPointSize (0),
77fDefaultExportFilename("G4OpenGL"),
78fSizeHasChanged(0),
79fGl2psDefaultLineWith(1),
80fGl2psDefaultPointSize(2),
81fGlViewInitialized(false),
82fIsGettingPickInfos(false)
83{
84 // Make changes to view parameters for OpenGL...
85 fVP.SetAutoRefresh(true);
86 fDefaultVP.SetAutoRefresh(true);
87 fGL2PSAction = new G4gl2ps();
88 tools_gl2ps_gl_funcs_t _funcs = {
89 (tools_glIsEnabled_func)glIsEnabled,
90 (tools_glBegin_func)glBegin,
91 (tools_glEnd_func)glEnd,
92 (tools_glGetFloatv_func)glGetFloatv,
93 (tools_glVertex3f_func)glVertex3f,
94 (tools_glGetBooleanv_func)glGetBooleanv,
95 (tools_glGetIntegerv_func)glGetIntegerv,
96 (tools_glRenderMode_func)glRenderMode,
97 (tools_glFeedbackBuffer_func)glFeedbackBuffer,
98 (tools_glPassThrough_func)glPassThrough
99 };
100 fGL2PSAction->setOpenGLFunctions(&_funcs);
101
102 // add supported export image format
107
108 // Change the default name
109 fExportFilename += fDefaultExportFilename + "_" + GetShortName().data();
110
111 // glClearColor (0.0, 0.0, 0.0, 0.0);
112 // glClearDepth (1.0);
113 // glDisable (GL_BLEND);
114 // glDisable (GL_LINE_SMOOTH);
115 // glDisable (GL_POLYGON_SMOOTH);
116
117}
118
123
125{
126 if (fWinSize_x == 0) {
127 fWinSize_x = fVP.GetWindowSizeHintX();
128 }
129 if (fWinSize_y == 0) {
130 fWinSize_y = fVP.GetWindowSizeHintY();
131 }
132
133 glClearColor (0.0, 0.0, 0.0, 0.0);
134 glClearDepth (1.0);
135 glDisable (GL_LINE_SMOOTH);
136 glDisable (GL_POLYGON_SMOOTH);
137 glDisable (GL_POINT_SMOOTH);
138
139// clear the buffers and window?
140 ClearView ();
141 FinishView ();
142
143 glDepthFunc (GL_LEQUAL);
144 glDepthMask (GL_TRUE);
145
146 glEnable (GL_BLEND);
147 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
148
149}
150
153
154 if(!isFramebufferReady()) {
155 return;
156 }
157
158 glFlush();
159}
160
161
163 // Ready for clear ?
164 // See : http://lists.apple.com/archives/mac-opengl/2012/Jul/msg00038.html
165 if(!isFramebufferReady()) {
166 return;
167 }
168
169 glClearColor (background.GetRed(),
170 background.GetGreen(),
171 background.GetBlue(),
172 1.);
173 glClearDepth (1.0);
174 //Below line does not compile with Mesa includes.
175 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
176 glClear (GL_COLOR_BUFFER_BIT);
177 glClear (GL_DEPTH_BUFFER_BIT);
178 glClear (GL_STENCIL_BUFFER_BIT);
179}
180
181
182void G4OpenGLViewer::ResizeWindow(unsigned int aWidth, unsigned int aHeight) {
183 if ((fWinSize_x != aWidth) || (fWinSize_y != aHeight)) {
184 fWinSize_x = aWidth;
185 fWinSize_y = aHeight;
186 fSizeHasChanged = true;
187 } else {
188 fSizeHasChanged = false;
189 }
190}
191
192/**
193 * Set the viewport of the scene
194 * MAXIMUM SIZE is :
195 * GLint dims[2];
196 * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
197 */
199{
200 // Check size
201 GLint dims[2];
202 dims[0] = 0;
203 dims[1] = 0;
204
205 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
206
207 if ((dims[0] !=0 ) && (dims[1] !=0)) {
208
209 if (fWinSize_x > (unsigned)dims[0]) {
210 G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<fWinSize_x <<" is resize to "<< dims[0] << G4endl;
211 fWinSize_x = dims[0];
212 }
213 if (fWinSize_y > (unsigned)dims[1]) {
214 G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<fWinSize_y <<" is resize to "<< dims[1] << G4endl;
215 fWinSize_y = dims[1];
216 }
217 }
218
219 glViewport(0, 0, fWinSize_x,fWinSize_y);
220
221
222}
223
224
226 // if getting pick infos, should not resize the view.
227 if (fIsGettingPickInfos) return;
228
229 if (!fSceneHandler.GetScene()) {
230 return;
231 }
232 // Calculates view representation based on extent of object being
233 // viewed and (initial) viewpoint. (Note: it can change later due
234 // to user interaction via visualization system's GUI.)
235
236 // Lighting.
237 GLfloat lightPosition [4];
238 lightPosition [0] = fVP.GetActualLightpointDirection().x();
239 lightPosition [1] = fVP.GetActualLightpointDirection().y();
240 lightPosition [2] = fVP.GetActualLightpointDirection().z();
241 lightPosition [3] = 0.;
242 // Light position is "true" light direction, so must come after gluLookAt.
243 GLfloat ambient [] = { 0.2f, 0.2f, 0.2f, 1.f};
244 GLfloat diffuse [] = { 0.8f, 0.8f, 0.8f, 1.f};
245 glEnable (GL_LIGHT0);
246 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
247 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
248
249 G4double ratioX = 1;
250 G4double ratioY = 1;
251 if (fWinSize_y > fWinSize_x) {
252 ratioX = ((G4double)fWinSize_y) / ((G4double)fWinSize_x);
253 }
254 if (fWinSize_x > fWinSize_y) {
255 ratioY = ((G4double)fWinSize_x) / ((G4double)fWinSize_y);
256 }
257
258 // Get radius of scene, etc.
259 // Note that this procedure properly takes into account zoom, dolly and pan.
260 const G4Point3D targetPoint
261 = fSceneHandler.GetScene()->GetStandardTargetPoint()
262 + fVP.GetCurrentTargetPoint ();
263 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
264 if(radius<=0.) radius = 1.;
265 const G4double cameraDistance = fVP.GetCameraDistance (radius);
266 const G4Point3D cameraPosition =
267 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
268 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
269 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
270 const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius) * ratioY;
271 const GLdouble left = -right;
272 const GLdouble top = fVP.GetFrontHalfHeight (pnear, radius) * ratioX;
273 const GLdouble bottom = -top;
274
275 // FIXME
276 ResizeGLView();
277 //SHOULD SetWindowsSizeHint()...
278
279 glMatrixMode (GL_PROJECTION); // set up Frustum.
280 glLoadIdentity();
281
282 const G4Vector3D scaleFactor = fVP.GetScaleFactor();
283 glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
284
285 if (fVP.GetFieldHalfAngle() == 0.) {
286 g4GlOrtho (left, right, bottom, top, pnear, pfar);
287 }
288 else {
289 g4GlFrustum (left, right, bottom, top, pnear, pfar);
290 }
291
292 glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
293 glLoadIdentity();
294
295 const G4Normal3D& upVector = fVP.GetUpVector ();
296 G4Point3D gltarget;
297 if (cameraDistance > 1.e-6 * radius) {
298 gltarget = targetPoint;
299 }
300 else {
301 gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
302 }
303
304 const G4Point3D& pCamera = cameraPosition; // An alias for brevity.
305
306 g4GluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
307 gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
308 upVector.x(), upVector.y(), upVector.z()); // Up vector.
309 // Light position is "true" light direction, so must come after gluLookAt.
310 glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
311
312 // The idea is to use back-to-back clipping planes. This can cut an object
313 // down to just a few pixels, which can make it difficult to see. So, for
314 // now, comment this out and use the generic (Boolean) method, via
315 // G4VSolid* G4OpenGLSceneHandler::CreateSectionSolid ()
316 // { return G4VSceneHandler::CreateSectionSolid(); }
317// if (fVP.IsSection () ) { // pair of back to back clip planes.
318// const G4Plane3D& sp = fVP.GetSectionPlane ();
319// double sArray[4];
320// sArray[0] = sp.a();
321// sArray[1] = sp.b();
322// sArray[2] = sp.c();
323// sArray[3] = sp.d() + radius * 1.e-05;
324// glClipPlane (GL_CLIP_PLANE0, sArray);
325// glEnable (GL_CLIP_PLANE0);
326// sArray[0] = -sp.a();
327// sArray[1] = -sp.b();
328// sArray[2] = -sp.c();
329// sArray[3] = -sp.d() + radius * 1.e-05;
330// glClipPlane (GL_CLIP_PLANE1, sArray);
331// glEnable (GL_CLIP_PLANE1);
332// } else {
333// glDisable (GL_CLIP_PLANE0);
334// glDisable (GL_CLIP_PLANE1);
335// }
336
337 // What we call intersection of cutaways is easy in OpenGL. You
338 // just keep cutting. Unions are more tricky - you have to have
339 // multiple passes and this is handled in
340 // G4OpenGLImmediate/StoredViewer::ProcessView.
341 const G4Planes& cutaways = fVP.GetCutawayPlanes();
342 size_t nPlanes = cutaways.size();
343 if (fVP.IsCutaway() &&
344 fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection) {
345 double a[4];
346 a[0] = cutaways[0].a();
347 a[1] = cutaways[0].b();
348 a[2] = cutaways[0].c();
349 a[3] = cutaways[0].d();
350 glClipPlane (GL_CLIP_PLANE2, a);
351 glEnable (GL_CLIP_PLANE2);
352 if (nPlanes > 1) {
353 a[0] = cutaways[1].a();
354 a[1] = cutaways[1].b();
355 a[2] = cutaways[1].c();
356 a[3] = cutaways[1].d();
357 glClipPlane (GL_CLIP_PLANE3, a);
358 glEnable (GL_CLIP_PLANE3);
359 }
360 if (nPlanes > 2) {
361 a[0] = cutaways[2].a();
362 a[1] = cutaways[2].b();
363 a[2] = cutaways[2].c();
364 a[3] = cutaways[2].d();
365 glClipPlane (GL_CLIP_PLANE4, a);
366 glEnable (GL_CLIP_PLANE4);
367 }
368 } else {
369 glDisable (GL_CLIP_PLANE2);
370 glDisable (GL_CLIP_PLANE3);
371 glDisable (GL_CLIP_PLANE4);
372 }
373
374 // Background.
375 background = fVP.GetBackgroundColour ();
376
377}
378
379
380
383 fRot_sens = 1;
384 fPan_sens = 0.01;
385}
386
387
389
390 //To perform haloing, first Draw all information to the depth buffer
391 //alone, using a chunky line width, and then Draw all info again, to
392 //the colour buffer, setting a thinner line width an the depth testing
393 //function to less than or equal, so if two lines cross, the one
394 //passing behind the other will not pass the depth test, and so not
395 //get rendered either side of the infront line for a short distance.
396
397 //First, disable writing to the colo(u)r buffer...
398 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
399
400 //Now enable writing to the depth buffer...
401 glDepthMask (GL_TRUE);
402 glDepthFunc (GL_LESS);
403 glClearDepth (1.0);
404
405 //Finally, set the line width to something wide...
406 ChangeLineWidth(3.0);
407
408}
409
411
412 //And finally, turn the colour buffer back on with a sesible line width...
413 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
414 glDepthFunc (GL_LEQUAL);
415 ChangeLineWidth(1.0);
416
417}
418
419G4String G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
420{
421 const std::vector < G4OpenGLViewerPickMap* > & pickMap = GetPickDetails(x,y);
422 G4String txt = "";
423 if (pickMap.size() == 0) {
424// txt += "No hits recorded.";;
425 } else {
426 for (unsigned int a=0; a < pickMap.size(); a++) {
427 if (pickMap[a]->getAttributes().size() > 0) {
428 txt += pickMap[a]->print();
429 }
430 }
431 }
432 return txt;
433}
434
435const std::vector < G4OpenGLViewerPickMap* > & G4OpenGLViewer::GetPickDetails(GLdouble x, GLdouble y)
436{
437 static std::vector < G4OpenGLViewerPickMap* > pickMapVector;
438 for (auto pickMap: pickMapVector) {
439 delete pickMap;
440 }
441 pickMapVector.clear();
442
443 const G4int BUFSIZE = 512;
444 GLuint selectBuffer[BUFSIZE];
445 glSelectBuffer(BUFSIZE, selectBuffer);
446 glRenderMode(GL_SELECT);
447 glInitNames();
448 glPushName(0);
449 glMatrixMode(GL_PROJECTION);
450 G4double currentProjectionMatrix[16];
451 glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
452 glPushMatrix();
453 glLoadIdentity();
454 GLint viewport[4];
455 glGetIntegerv(GL_VIEWPORT, viewport);
456/* G4cout
457 << "viewport, x,y: "
458 << viewport[0] << ',' << viewport[1] << ',' << viewport[2] << ',' << viewport[3]
459 << ", " << x << ',' << y
460 << G4endl;
461*/
462 fIsGettingPickInfos = true;
463 // Define 5x5 pixel pick area
464 g4GluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
465 glMultMatrixd(currentProjectionMatrix);
466 glMatrixMode(GL_MODELVIEW);
467 DrawView();
468 GLint hits = glRenderMode(GL_RENDER);
469 fIsGettingPickInfos = false;
470 if (hits < 0) {
471 G4cout << "Too many hits. Zoom in to reduce overlaps." << G4endl;
472 goto restoreMatrices;
473 }
474 if (hits > 0) {
475 GLuint* p = selectBuffer;
476 for (GLint i = 0; i < hits; ++i) {
477 GLuint nnames = *p++;
478 // This bit of debug code or...
479 //GLuint zmin = *p++;
480 //GLuint zmax = *p++;
481 //G4cout << "Hit " << i << ": " << nnames << " names"
482 // << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
483 // ...just increment the pointer
484 p++;
485 p++;
486 for (GLuint j = 0; j < nnames; ++j) {
487 GLuint name = *p++;
488 std::map<GLuint, G4AttHolder*>::iterator iter =
489 fOpenGLSceneHandler.fPickMap.find(name);
490 if (iter != fOpenGLSceneHandler.fPickMap.end()) {
491 G4AttHolder* attHolder = iter->second;
492 if(attHolder && attHolder->GetAttDefs().size()) {
493 for (size_t iAtt = 0;
494 iAtt < attHolder->GetAttDefs().size(); ++iAtt) {
495 std::ostringstream oss;
496 oss << G4AttCheck(attHolder->GetAttValues()[iAtt],
497 attHolder->GetAttDefs()[iAtt]);
499// G4cout
500// << "i,j, attHolder->GetAttDefs().size(): "
501// << i << ',' << j
502// << ", " << attHolder->GetAttDefs().size()
503// << G4endl;
504// G4cout << "G4OpenGLViewer::GetPickDetails: " << oss.str() << G4endl;
505 pickMap->addAttributes(oss.str());
506 pickMap->setHitNumber(i);
507 pickMap->setSubHitNumber(j);
508 pickMap->setPickName(name);
509 pickMapVector.push_back(pickMap);
510 }
511 }
512 }
513 }
514 }
515 }
516
517restoreMatrices:
518 glMatrixMode(GL_PROJECTION);
519 glPopMatrix();
520 glMatrixMode(GL_MODELVIEW);
521
522 return pickMapVector;
523}
524
525GLubyte* G4OpenGLViewer::grabPixels
526(int inColor, unsigned int width, unsigned int height) {
527
528 GLubyte* buffer;
529 GLint swapbytes, lsbfirst, rowlength;
530 GLint skiprows, skippixels, alignment;
531 GLenum format;
532 int size;
533
534 if (inColor) {
535 format = GL_RGB;
536 size = width*height*3;
537 } else {
538 format = GL_LUMINANCE;
539 size = width*height*1;
540 }
541
542 buffer = new GLubyte[size];
543 if (buffer == NULL)
544 return NULL;
545
546 glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
547 glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
548 glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
549
550 glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
551 glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
552 glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
553
554 glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
555 glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
556 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
557
558 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
559 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
560 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
561
562 glReadBuffer(GL_FRONT);
563 glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
564
565 glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
566 glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
567 glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
568
569 glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
570 glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
571 glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
572
573 return buffer;
574}
575
576bool G4OpenGLViewer::printVectoredEPS() {
577 return printGl2PS();
578}
579
580bool G4OpenGLViewer::printNonVectoredEPS () {
581
582 int width = getRealExportWidth();
583 int height = getRealExportHeight();
584
585 FILE* fp;
586 GLubyte* pixels;
587 GLubyte* curpix;
588 int components, pos, i;
589
590 pixels = grabPixels (fPrintColour, width, height);
591
592 if (pixels == NULL) {
593 G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
594 return false;
595 }
596 if (fPrintColour) {
597 components = 3;
598 } else {
599 components = 1;
600 }
601 std::string name = getRealPrintFilename();
602 fp = fopen (name.c_str(), "w");
603 if (fp == NULL) {
604 G4cerr << "Can't open filename " << name.c_str() << G4endl;
605 return false;
606 }
607
608 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
609 fprintf (fp, "%%%%Title: %s\n", name.c_str());
610 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
611 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
612 fprintf (fp, "%%%%EndComments\n");
613 fprintf (fp, "gsave\n");
614 fprintf (fp, "/bwproc {\n");
615 fprintf (fp, " rgbproc\n");
616 fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
617 fprintf (fp, " 5 -1 roll {\n");
618 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
619 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
620 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
621 fprintf (fp, " { 2 1 roll } ifelse\n");
622 fprintf (fp, " }forall\n");
623 fprintf (fp, " pop pop pop\n");
624 fprintf (fp, "} def\n");
625 fprintf (fp, "systemdict /colorimage known not {\n");
626 fprintf (fp, " /colorimage {\n");
627 fprintf (fp, " pop\n");
628 fprintf (fp, " pop\n");
629 fprintf (fp, " /rgbproc exch def\n");
630 fprintf (fp, " { bwproc } image\n");
631 fprintf (fp, " } def\n");
632 fprintf (fp, "} if\n");
633 fprintf (fp, "/picstr %d string def\n", width * components);
634 fprintf (fp, "%d %d scale\n", width, height);
635 fprintf (fp, "%d %d %d\n", width, height, 8);
636 fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
637 fprintf (fp, "{currentfile picstr readhexstring pop}\n");
638 fprintf (fp, "false %d\n", components);
639 fprintf (fp, "colorimage\n");
640
641 curpix = (GLubyte*) pixels;
642 pos = 0;
643 for (i = width*height*components; i>0; i--) {
644 fprintf (fp, "%02hx ", (unsigned short)(*(curpix++)));
645 if (++pos >= 32) {
646 fprintf (fp, "\n");
647 pos = 0;
648 }
649 }
650 if (pos)
651 fprintf (fp, "\n");
652
653 fprintf (fp, "grestore\n");
654 fprintf (fp, "showpage\n");
655 delete [] pixels;
656 fclose (fp);
657
658 // Reset for next time (useful if size change)
659 // fPrintSizeX = -1;
660 // fPrintSizeY = -1;
661
662 return true;
663}
664
665/** Return if gl2ps is currently writing
666 */
668
669 if (!fGL2PSAction) return false;
670 if (fGL2PSAction->fileWritingEnabled()) {
671 return true;
672 }
673 return false;
674}
675
676
678 bool check = false;
679#ifdef G4VIS_BUILD_OPENGLQT_DRIVER
680 check = true;
681#endif
682#ifdef G4VIS_BUILD_OPENGLX_DRIVER
683 check = false;
684#endif
685#ifdef G4VIS_BUILD_OPENGLXM_DRIVER
686 check = false;
687#endif
688#ifdef G4VIS_BUILD_OPENGLWIN32_DRIVER
689 check = false;
690#endif
691
692#if GL_ARB_framebuffer_object
693 if (check) {
694// if ( glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNDEFINED) {
695// return false;
696// }
697 }
698#endif
699 return true;
700}
701
702
703/* Draw Gl2Ps text if needed
704 */
706{
707 // gl2ps or GL window ?
708 if (isGl2psWriting()) {
709
711 G4double size = fSceneHandler.GetMarkerSize(g4text,sizeType);
712 G4Point3D position = g4text.GetPosition();
713
714 G4String textString = g4text.GetText();
715
716 glRasterPos3d(position.x(),position.y(),position.z());
717 GLint align = GL2PS_TEXT_B;
718
719 switch (g4text.GetLayout()) {
720 case G4Text::left: align = GL2PS_TEXT_BL; break;
721 case G4Text::centre: align = GL2PS_TEXT_B; break;
722 case G4Text::right: align = GL2PS_TEXT_BR;
723 }
724
725 fGL2PSAction->addTextOpt(textString.c_str(),"Times-Roman",GLshort(size),align,0);
726
727 } else {
728
729 static G4int callCount = 0;
730 ++callCount;
731 //if (callCount <= 10 || callCount%100 == 0) {
732 if (callCount <= 1) {
733 G4cout <<
734 "G4OpenGLViewer::DrawText: Not implemented for \""
735 << fName <<
736 "\"\n Called with "
737 << g4text
738 << G4endl;
739 }
740 }
741}
742
743/** Change PointSize on gl2ps if needed
744 */
746
747 if (isGl2psWriting()) {
748 fGL2PSAction->setPointSize(int(size));
749 } else {
750 glPointSize (size);
751 }
752}
753
754
755/** Change LineSize on gl2ps if needed
756 */
758
759 if (isGl2psWriting()) {
760 fGL2PSAction->setLineWidth(int(width));
761 } else {
762 glLineWidth (width);
763 }
764}
765
766/**
767 Export image with the given name with width and height
768 Several cases :
769 If name is "", filename will have the default value
770 If name is "toto.png", set the name to "toto" and the format to "png". No incremented suffix is added.
771 If name is "toto", set the name to "toto" and the format to default (or current format if specify).
772 Will also add an incremented suffix at the end of the file
773*/
774bool G4OpenGLViewer::exportImage(std::string name, int width, int height) {
775
776 if (! setExportFilename(name)) {
777 return false;
778 }
779
780 if ((width != -1) && (height != -1)) {
781 setExportSize(width, height);
782 }
783
784 if (fExportImageFormat == "eps") {
785 fGL2PSAction->setExportImageFormat_EPS();
786 } else if (fExportImageFormat == "ps") {
787 fGL2PSAction->setExportImageFormat_PS();
788 } else if (fExportImageFormat == "svg") {
789 fGL2PSAction->setExportImageFormat_SVG();
790 } else if (fExportImageFormat == "pdf") {
791 fGL2PSAction->setExportImageFormat_PDF();
792 } else {
793 setExportImageFormat(fExportImageFormat,true); // will display a message if this format is not correct for the current viewer
794 return false;
795 }
796
797 bool res;
798
799 // Change the LC_NUMERIC value in order to have "." separtor and not ","
800 // This case is only useful for French, Canadien...
801 size_t len = strlen(setlocale(LC_NUMERIC,NULL));
802 char* oldLocale = (char*)(malloc(len+1));
803 if(oldLocale!=NULL) strncpy(oldLocale,setlocale(LC_NUMERIC,NULL),len);
804 setlocale(LC_NUMERIC,"C");
805
806 if (((fExportImageFormat == "eps") || (fExportImageFormat == "ps")) && (!fVectoredPs)) {
807 res = printNonVectoredEPS();
808 } else {
809 res = printVectoredEPS();
810 }
811
812 // restore the local
813 if (oldLocale) {
814 setlocale(LC_NUMERIC,oldLocale);
815 free(oldLocale);
816 }
817
818 if (res == false) {
819 G4cerr << "Error saving file... " << getRealPrintFilename().c_str() << G4endl;
820 } else {
821 G4cout << "File " << getRealPrintFilename().c_str() << " size: " << getRealExportWidth() << "x" << getRealExportHeight() << " has been saved " << G4endl;
822
823 // increment index if necessary
824 if ( fExportFilenameIndex != -1) {
826 }
827 }
828
829 return res;
830}
831
832
833bool G4OpenGLViewer::printGl2PS() {
834
835 int width = getRealExportWidth();
836 int height = getRealExportHeight();
837 bool res = true;
838
839 // no need to redraw at each new primitive for printgl2PS
840 G4OpenGLSceneHandler& oglSceneHandler = dynamic_cast<G4OpenGLSceneHandler&>(fSceneHandler);
841 G4OpenGLSceneHandler::FlushAction originalFlushAction = oglSceneHandler.GetFlushAction();
843
844 if (!fGL2PSAction) return false;
845
847 // try to resize
848 int X = fWinSize_x;
849 int Y = fWinSize_y;
850
851 fWinSize_x = width;
852 fWinSize_y = height;
853 // Laurent G. 16/03/10 : Not the good way to do.
854 // We should draw in a new offscreen context instead of
855 // resizing and drawing in current window...
856 // This should be solve when we will do an offscreen method
857 // to render OpenGL
858 // See :
859 // http://developer.apple.com/Mac/library/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_offscreen/opengl_offscreen.html
860 // http://www.songho.ca/opengl/gl_fbo.html
861
862 ResizeGLView();
863 bool extendBuffer = true;
864 bool endWriteAction = false;
865 bool beginWriteAction = true;
866 bool filePointerOk = true;
867 while ((extendBuffer) && (! endWriteAction) && (filePointerOk)) {
868
869 beginWriteAction = fGL2PSAction->enableFileWriting();
870 if(beginWriteAction) {
871 GLint vp[4];
872 ::glGetIntegerv(GL_VIEWPORT,vp);
873 fGL2PSAction->setViewport(vp[0],vp[1],vp[2],vp[3]);
874 beginWriteAction = fGL2PSAction->beginPage();
875 }
876
877 // 3 cases :
878 // - true
879 // - false && ! fGL2PSAction->fileWritingEnabled() => bad file name
880 // - false && fGL2PSAction->fileWritingEnabled() => buffer size problem ?
881
882 filePointerOk = fGL2PSAction->fileWritingEnabled();
883
884 if (beginWriteAction) {
885
886 // Set the viewport
887 // By default, we choose the line width (trajectories...)
888 fGL2PSAction->setLineWidth(fGl2psDefaultLineWith);
889 // By default, we choose the point size (markers...)
890 fGL2PSAction->setPointSize(fGl2psDefaultPointSize);
891
892 DrawView ();
893
894 endWriteAction = fGL2PSAction->endPage();
895 fGL2PSAction->disableFileWriting();
896 }
897 if (filePointerOk) {
898 if ((! endWriteAction) || (! beginWriteAction)) {
899 extendBuffer = fGL2PSAction->extendBufferSize();
900 }
901 }
902 }
903 fGL2PSAction->resetBufferSizeParameters();
904
905 if (!extendBuffer ) {
906 G4cerr << "ERROR: gl2ps buffer size is not big enough to print this geometry. Try to extend it. No output produced"<< G4endl;
907 res = false;
908 }
909 if (!beginWriteAction ) {
910 G4cerr << "ERROR: saving file "<<getRealPrintFilename().c_str()<<". Check read/write access. No output produced" << G4endl;
911 res = false;
912 }
913 if (!endWriteAction ) {
914 G4cerr << "gl2ps error. No output produced" << G4endl;
915 res = false;
916 }
917 fWinSize_x = X;
918 fWinSize_y = Y;
919
920 oglSceneHandler.SetFlushAction(originalFlushAction);
921
922 // Reset for next time (useful is size change)
923 // fPrintSizeX = 0;
924 // fPrintSizeY = 0;
925
926 return res;
927}
928
929unsigned int G4OpenGLViewer::getWinWidth() const{
930 return fWinSize_x;
931}
932
933unsigned int G4OpenGLViewer::getWinHeight() const{
934 return fWinSize_y;
935}
936
938 return fSizeHasChanged;
939}
940
941G4int G4OpenGLViewer::getRealExportWidth() {
942 if (fPrintSizeX == -1) {
943 return fWinSize_x;
944 }
945 GLint dims[2];
946 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
947
948 // L.Garnier 01-2010: Some problems with mac 10.6
949 if ((dims[0] !=0 ) && (dims[1] !=0)) {
950 if (fPrintSizeX > dims[0]){
951 return dims[0];
952 }
953 }
954 if (fPrintSizeX < -1){
955 return 0;
956 }
957 return fPrintSizeX;
958}
959
960G4int G4OpenGLViewer::getRealExportHeight() {
961 if (fPrintSizeY == -1) {
962 return fWinSize_y;
963 }
964 GLint dims[2];
965 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
966
967 // L.Garnier 01-2010: Some problems with mac 10.6
968 if ((dims[0] !=0 ) && (dims[1] !=0)) {
969 if (fPrintSizeY > dims[1]){
970 return dims[1];
971 }
972 }
973 if (fPrintSizeY < -1){
974 return 0;
975 }
976 return fPrintSizeY;
977}
978
983
984/**
985 If name is "" or "!", filename and extension will have the default value.
986 If name is "toto.png", set the name to "toto" and the format to "png". No incremented suffix is added.
987 If name is "toto", set the name to "toto" and the format to default (or current format if specify).
988 If name is the same as previous, do not reset incremented suffix.
989*/
991 if (name == "!") {
992 name = "";
993 }
994
995 if (inc) {
996 if ((name != "") && (fExportFilename != name)) {
998 }
999 } else {
1001 }
1002
1003 if (name.size() == 0) {
1004 name = getRealPrintFilename().c_str();
1005 } else {
1006 // guess format by extention
1007 std::string extension = name.substr(name.find_last_of(".") + 1);
1008 // If there is a dot in the name the above might find rubbish, so...
1009 if (extension.size() >= 3 && extension.size() <= 4) { // Possible extension
1010 if (setExportImageFormat(extension, false)) { // Extension found
1011 fExportFilename = name.substr(0,name.find_last_of("."));
1012 } else { // No viable extension found
1013 return false;
1014 }
1015 } else { // Assume name is already the required without-extension part
1016 fExportFilename = name;
1017 }
1018 }
1019 return true;
1020}
1021
1023 std::string temp = fExportFilename;
1024 if (fExportFilenameIndex != -1) {
1025 temp += std::string("_");
1026 std::ostringstream os;
1027 os << std::setw(4) << std::setfill('0') << fExportFilenameIndex;
1028 std::string nb_str = os.str();
1029 temp += nb_str;
1030 }
1031 temp += "."+fExportImageFormat;
1032 return temp;
1033}
1034
1036{
1037 if (!fSceneHandler.GetScene()) {
1038 return 0;
1039 }
1040 const G4Point3D targetPoint
1041 = fSceneHandler.GetScene()->GetStandardTargetPoint()
1042 + fVP.GetCurrentTargetPoint ();
1043 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1044 if(radius<=0.) radius = 1.;
1045 const G4double cameraDistance = fVP.GetCameraDistance (radius);
1046 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1047 return 2 * fVP.GetFrontHalfHeight (pnear, radius);
1048}
1049
1051{
1052 if (!fSceneHandler.GetScene()) {
1053 return 0;
1054 }
1055 const G4Point3D targetPoint
1056 = fSceneHandler.GetScene()->GetStandardTargetPoint()
1057 + fVP.GetCurrentTargetPoint ();
1058 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1059 if(radius<=0.) radius = 1.;
1060 const G4double cameraDistance = fVP.GetCameraDistance (radius);
1061 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1062 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
1063 return 2 * fVP.GetFrontHalfHeight (pfar, radius);
1064}
1065
1066
1068{
1069 if (!fSceneHandler.GetScene()) {
1070 return 0;
1071 }
1072 const G4Point3D targetPoint
1073 = fSceneHandler.GetScene()->GetStandardTargetPoint()
1074 + fVP.GetCurrentTargetPoint ();
1075 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1076 if(radius<=0.) radius = 1.;
1077 const G4double cameraDistance = fVP.GetCameraDistance (radius);
1078 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
1079 return fVP.GetFarDistance (cameraDistance, pnear, radius)- pnear;
1080}
1081
1082
1083
1085{
1086 if (fVP.GetRotationStyle() == G4ViewParameters::freeRotation) {
1087 rotateSceneInViewDirection(dx,dy);
1088 } else {
1089 if( dx != 0) {
1090 rotateSceneThetaPhi(dx,0);
1091 }
1092 if( dy != 0) {
1093 rotateSceneThetaPhi(0,dy);
1094 }
1095 }
1096}
1097
1098
1100{
1101 if (fVP.GetRotationStyle() != G4ViewParameters::freeRotation) {
1102 rotateSceneInViewDirection(dx,dy);
1103 } else {
1104 if( dx != 0) {
1105 rotateSceneThetaPhi(dx,0);
1106 }
1107 if( dy != 0) {
1108 rotateSceneThetaPhi(0,dy);
1109 }
1110 }
1111}
1112
1113void G4OpenGLViewer::rotateSceneThetaPhi(G4double dx, G4double dy)
1114{
1115 if (!fSceneHandler.GetScene()) {
1116 return;
1117 }
1118
1119 G4Vector3D vp;
1120 G4Vector3D up;
1121
1122 G4Vector3D xprime;
1123 G4Vector3D yprime;
1124 G4Vector3D zprime;
1125
1126 G4double delta_alpha;
1127 G4double delta_theta;
1128
1129 G4Vector3D new_vp;
1130 G4Vector3D new_up;
1131
1132 G4double cosalpha;
1133 G4double sinalpha;
1134
1135 G4Vector3D a1;
1136 G4Vector3D a2;
1137 G4Vector3D delta;
1138 G4Vector3D viewPoint;
1139
1140
1141 //phi spin stuff here
1142
1143 vp = fVP.GetViewpointDirection ().unit ();
1144 up = fVP.GetUpVector ().unit ();
1145
1146 yprime = (up.cross(vp)).unit();
1147 zprime = (vp.cross(yprime)).unit();
1148
1149 if (fVP.GetLightsMoveWithCamera()) {
1150 delta_alpha = dy * fRot_sens;
1151 delta_theta = -dx * fRot_sens;
1152 } else {
1153 delta_alpha = -dy * fRot_sens;
1154 delta_theta = dx * fRot_sens;
1155 }
1156
1157 delta_alpha *= CLHEP::deg;
1158 delta_theta *= CLHEP::deg;
1159
1160 new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1161
1162 // to avoid z rotation flipping
1163 // to allow more than 360° rotation
1164
1165 if (fVP.GetLightsMoveWithCamera()) {
1166 new_up = (new_vp.cross(yprime)).unit();
1167 if (new_vp.z()*vp.z() <0) {
1168 new_up.set(new_up.x(),-new_up.y(),new_up.z());
1169 }
1170 } else {
1171 new_up = up;
1172 if (new_vp.z()*vp.z() <0) {
1173 new_up.set(new_up.x(),-new_up.y(),new_up.z());
1174 }
1175 }
1176 fVP.SetUpVector(new_up);
1177 ////////////////
1178 // Rotates by fixed azimuthal angle delta_theta.
1179
1180 cosalpha = new_up.dot (new_vp.unit());
1181 sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1182 yprime = (new_up.cross (new_vp.unit())).unit ();
1183 xprime = yprime.cross (new_up);
1184 // Projection of vp on plane perpendicular to up...
1185 a1 = sinalpha * xprime;
1186 // Required new projection...
1187 a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1188 // Required Increment vector...
1189 delta = a2 - a1;
1190 // So new viewpoint is...
1191 viewPoint = new_vp.unit() + delta;
1192
1193 fVP.SetViewAndLights (viewPoint);
1194}
1195
1196
1197void G4OpenGLViewer::rotateSceneInViewDirection(G4double dx, G4double dy)
1198{
1199 if (!fSceneHandler.GetScene()) {
1200 return;
1201 }
1202
1203 G4Vector3D vp;
1204 G4Vector3D up;
1205
1206 G4Vector3D xprime;
1207 G4Vector3D yprime;
1208 G4Vector3D zprime;
1209
1210 G4Vector3D new_vp;
1211 G4Vector3D new_up;
1212
1213 G4Vector3D a1;
1214 G4Vector3D a2;
1215 G4Vector3D delta;
1216 G4Vector3D viewPoint;
1217
1218 dx = dx/100;
1219 dy = dy/100;
1220
1221 //phi spin stuff here
1222
1223 vp = fVP.GetViewpointDirection ().unit();
1224 up = fVP.GetUpVector ().unit();
1225
1226 G4Vector3D zPrimeVector = G4Vector3D(up.y()*vp.z()-up.z()*vp.y(),
1227 up.z()*vp.x()-up.x()*vp.z(),
1228 up.x()*vp.y()-up.y()*vp.x());
1229
1230 viewPoint = vp/fRot_sens + (zPrimeVector*dx - up*dy) ;
1231 new_up = G4Vector3D(viewPoint.y()*zPrimeVector.z()-viewPoint.z()*zPrimeVector.y(),
1232 viewPoint.z()*zPrimeVector.x()-viewPoint.x()*zPrimeVector.z(),
1233 viewPoint.x()*zPrimeVector.y()-viewPoint.y()*zPrimeVector.x());
1234
1235 G4Vector3D new_upUnit = new_up.unit();
1236
1237
1238
1239 fVP.SetUpVector(new_upUnit);
1240 fVP.SetViewAndLights (viewPoint);
1241}
1242
1243
1245 fExportImageFormatVector.push_back(format);
1246}
1247
1248bool G4OpenGLViewer::setExportImageFormat(std::string format, bool quiet) {
1249 bool found = false;
1250 std::string list;
1251 for (unsigned int a=0; a<fExportImageFormatVector.size(); a++) {
1252 list +=fExportImageFormatVector.at(a) + " ";
1253
1254 if (fExportImageFormatVector.at(a) == format) {
1255 if (! quiet) {
1256 G4cout << " Changing export format to \"" << format << "\"" << G4endl;
1257 }
1258 if (format != fExportImageFormat) {
1260 fExportImageFormat = format;
1261 }
1262 return true;
1263 }
1264 }
1265 if (! found) {
1266 if (format.size() == 0) {
1267 G4cout << " Current formats availables are : " << list << G4endl;
1268 } else {
1269 G4cerr << " Format \"" << format << "\" is not available for the selected viewer. Current formats availables are : " << list << G4endl;
1270 }
1271 }
1272 return false;
1273}
1274
1275
1276// From MESA implementation :
1277// http://www.techques.com/question/1-8660454/gluPickMatrix-code-from-Mesa
1278
1279void G4OpenGLViewer::g4GluPickMatrix(GLdouble x, GLdouble y, GLdouble width, GLdouble height,
1280 GLint viewport[4])
1281 {
1282 GLdouble mat[16];
1283 GLdouble sx, sy;
1284 GLdouble tx, ty;
1285
1286 sx = viewport[2] / width;
1287 sy = viewport[3] / height;
1288 tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
1289 ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
1290
1291#define M(row, col) mat[col*4+row]
1292 M(0, 0) = sx;
1293 M(0, 1) = 0.0;
1294 M(0, 2) = 0.0;
1295 M(0, 3) = tx;
1296 M(1, 0) = 0.0;
1297 M(1, 1) = sy;
1298 M(1, 2) = 0.0;
1299 M(1, 3) = ty;
1300 M(2, 0) = 0.0;
1301 M(2, 1) = 0.0;
1302 M(2, 2) = 1.0;
1303 M(2, 3) = 0.0;
1304 M(3, 0) = 0.0;
1305 M(3, 1) = 0.0;
1306 M(3, 2) = 0.0;
1307 M(3, 3) = 1.0;
1308#undef M
1309
1310 glMultMatrixd(mat);
1311}
1312
1313
1314
1315
1316
1317// From MESA implementation :
1318// https://github.com/jlamarche/iOS-OpenGLES-Stuff/blob/master/Wavefront%20OBJ%20Loader/Classes/gluLookAt.m
1319// or http://www.daniweb.com/software-development/game-development/threads/308901/lookat-matrix-source-code
1320
1321void G4OpenGLViewer::g4GluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
1322 GLdouble centerx, GLdouble centery, GLdouble
1323 centerz,
1324 GLdouble upx, GLdouble upy, GLdouble upz )
1325{
1326 GLdouble mat[16];
1327 GLdouble x[3], y[3], z[3];
1328 GLdouble mag;
1329
1330 /* Make rotation matrix */
1331
1332 /* Z vector */
1333 z[0] = eyex - centerx;
1334 z[1] = eyey - centery;
1335 z[2] = eyez - centerz;
1336 mag = std::sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
1337 if (mag) { /* mpichler, 19950515 */
1338 z[0] /= mag;
1339 z[1] /= mag;
1340 z[2] /= mag;
1341 }
1342
1343 /* Y vector */
1344 y[0] = upx;
1345 y[1] = upy;
1346 y[2] = upz;
1347
1348 /* X vector = Y cross Z */
1349 x[0] = y[1] * z[2] - y[2] * z[1];
1350 x[1] = -y[0] * z[2] + y[2] * z[0];
1351 x[2] = y[0] * z[1] - y[1] * z[0];
1352
1353 /* Recompute Y = Z cross X */
1354 y[0] = z[1] * x[2] - z[2] * x[1];
1355 y[1] = -z[0] * x[2] + z[2] * x[0];
1356 y[2] = z[0] * x[1] - z[1] * x[0];
1357
1358 /* mpichler, 19950515 */
1359 /* cross product gives area of parallelogram, which is < 1.0 for
1360 * non-perpendicular unit-length vectors; so normalize x, y here
1361 */
1362
1363 mag = std::sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
1364 if (mag) {
1365 x[0] /= mag;
1366 x[1] /= mag;
1367 x[2] /= mag;
1368 }
1369
1370 mag = std::sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
1371 if (mag) {
1372 y[0] /= mag;
1373 y[1] /= mag;
1374 y[2] /= mag;
1375 }
1376
1377#define M(row,col) mat[col*4+row]
1378 M(0, 0) = x[0];
1379 M(0, 1) = x[1];
1380 M(0, 2) = x[2];
1381 M(0, 3) = 0.0;
1382 M(1, 0) = y[0];
1383 M(1, 1) = y[1];
1384 M(1, 2) = y[2];
1385 M(1, 3) = 0.0;
1386 M(2, 0) = z[0];
1387 M(2, 1) = z[1];
1388 M(2, 2) = z[2];
1389 M(2, 3) = 0.0;
1390 M(3, 0) = 0.0;
1391 M(3, 1) = 0.0;
1392 M(3, 2) = 0.0;
1393 M(3, 3) = 1.0;
1394#undef M
1395 glMultMatrixd(mat);
1396
1397 /* Translate Eye to Origin */
1398 glTranslated(-eyex, -eyey, -eyez);
1399}
1400
1401void G4OpenGLViewer::g4GlOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) {
1402 // glOrtho (left, right, bottom, top, near, far);
1403
1404 GLdouble a = 2.0 / (right - left);
1405 GLdouble b = 2.0 / (top - bottom);
1406 GLdouble c = -2.0 / (zFar - zNear);
1407
1408 GLdouble tx = - (right + left)/(right - left);
1409 GLdouble ty = - (top + bottom)/(top - bottom);
1410 GLdouble tz = - (zFar + zNear)/(zFar - zNear);
1411
1412 GLdouble ortho[16] = {
1413 a, 0, 0, 0,
1414 0, b, 0, 0,
1415 0, 0, c, 0,
1416 tx, ty, tz, 1
1417 };
1418 glMultMatrixd(ortho);
1419
1420}
1421
1422
1423void G4OpenGLViewer::g4GlFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) {
1424 // glFrustum (left, right, bottom, top, near, far);
1425
1426 GLdouble deltaX = right - left;
1427 GLdouble deltaY = top - bottom;
1428 GLdouble deltaZ = zFar - zNear;
1429
1430 GLdouble a = 2.0f * zNear / deltaX;
1431 GLdouble b = 2.0f * zNear / deltaY;
1432 GLdouble c = (right + left) / deltaX;
1433 GLdouble d = (top + bottom) / deltaY;
1434 GLdouble e = -(zFar + zNear) / (zFar - zNear);
1435 GLdouble f = -2.0f * zFar * zNear / deltaZ;
1436
1437 GLdouble proj[16] = {
1438 a, 0, 0, 0,
1439 0, b, 0, 0,
1440 c, d, e, -1.0f,
1441 0, 0, f, 0
1442 };
1443
1444 glMultMatrixd(proj);
1445
1446}
1447
1449 std::ostringstream txt;
1450 for (unsigned int a=0; a<fAttributes.size(); a++) {
1451 txt << fAttributes[a];
1452 if (a < fAttributes.size() - 1) txt << "\n";
1453 }
1454 return txt.str();
1455}
G4double Y(G4double density)
HepGeom::Normal3D< G4double > G4Normal3D
Definition G4Normal3D.hh:34
#define GL2PS_TEXT_BL
#define M(row, col)
#define GL2PS_TEXT_BR
#define GL2PS_TEXT_B
HepGeom::Point3D< G4double > G4Point3D
Definition G4Point3D.hh:34
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
HepGeom::Vector3D< G4double > G4Vector3D
Definition G4Vector3D.hh:34
std::vector< G4Plane3D > G4Planes
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
const std::vector< const std::vector< G4AttValue > * > & GetAttValues() const
const std::vector< const std::map< G4String, G4AttDef > * > & GetAttDefs() const
static void SetFlushAction(FlushAction action)
static FlushAction GetFlushAction()
void setSubHitNumber(G4int n)
void setHitNumber(G4int n)
void addAttributes(G4String att)
void setPickName(G4int n)
virtual void SetView()
unsigned int fWinSize_y
void g4GluPickMatrix(GLdouble x, GLdouble y, GLdouble width, GLdouble height, GLint viewport[4])
void g4GlFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
std::vector< std::string > fExportImageFormatVector
friend class G4OpenGLSceneHandler
void g4GluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz)
void rotateSceneToggle(G4double dx, G4double dy)
bool setExportImageFormat(std::string format, bool quiet=false)
virtual void ResetView()
unsigned int getWinHeight() const
std::string fExportImageFormat
void ClearViewWithoutFlush()
void ResizeWindow(unsigned int, unsigned int)
unsigned int getWinWidth() const
std::string fDefaultExportImageFormat
bool setExportFilename(G4String name, G4bool inc=true)
G4OpenGLViewer(G4OpenGLSceneHandler &scene)
void addExportImageFormat(std::string format)
G4bool antialiasing_enabled
void ChangeLineWidth(G4double width)
virtual void DrawText(const G4Text &)
virtual void ClearView()
GLdouble getSceneFarWidth()
void setExportSize(G4int, G4int)
virtual G4String Pick(GLdouble x, GLdouble y)
void rotateScene(G4double dx, G4double dy)
void ChangePointSize(G4double size)
GLdouble getSceneDepth()
G4bool isFramebufferReady()
G4bool transparency_enabled
virtual bool exportImage(std::string name="", int width=-1, int height=-1)
void g4GlOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
G4gl2ps * fGL2PSAction
G4bool isGl2psWriting()
G4bool sizeHasChanged()
G4OpenGLSceneHandler & fOpenGLSceneHandler
virtual ~G4OpenGLViewer()
unsigned int fWinSize_x
std::string getRealPrintFilename()
G4double GetSceneNearWidth()
const std::vector< G4OpenGLViewerPickMap * > & GetPickDetails(GLdouble x, GLdouble y)
Layout GetLayout() const
G4String GetText() const
@ centre
Definition G4Text.hh:76
@ right
Definition G4Text.hh:76
@ left
Definition G4Text.hh:76
G4Point3D GetPosition() const
G4Scene * GetScene() const
virtual void DrawView()=0
G4VSceneHandler & fSceneHandler
Definition G4VViewer.hh:268
G4String fName
Definition G4VViewer.hh:270
G4ViewParameters fDefaultVP
Definition G4VViewer.hh:273
const G4String & GetShortName() const
G4ViewParameters fVP
Definition G4VViewer.hh:272
virtual void FinishView()
Definition G4VViewer.cc:108
G4VViewer(G4VSceneHandler &, G4int id, const G4String &name="")
Definition G4VViewer.cc:49
virtual void ResetView()
void setFileName(const char *)
Definition G4gl2ps.cc:114
bool beginPage()
Definition G4gl2ps.cc:178
void setViewport(int, int, int, int)
Definition G4gl2ps.cc:107
bool enableFileWriting()
Definition G4gl2ps.cc:118
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
tools_GLint(* tools_glRenderMode_func)(tools_GLenum)
Definition gl2ps_def.h:195
void(* tools_glVertex3f_func)(tools_GLfloat, tools_GLfloat, tools_GLfloat)
Definition gl2ps_def.h:192
void(* tools_glGetFloatv_func)(tools_GLenum, tools_GLfloat *)
Definition gl2ps_def.h:191
void(* tools_glBegin_func)(tools_GLenum)
Definition gl2ps_def.h:189
void(* tools_glFeedbackBuffer_func)(tools_GLsizei, tools_GLenum, tools_GLfloat *)
Definition gl2ps_def.h:196
void(* tools_glPassThrough_func)(tools_GLfloat)
Definition gl2ps_def.h:197
void(* tools_glGetBooleanv_func)(tools_GLenum, tools_GLboolean *)
Definition gl2ps_def.h:193
void(* tools_glEnd_func)()
Definition gl2ps_def.h:190
void(* tools_glGetIntegerv_func)(tools_GLenum, tools_GLint *)
Definition gl2ps_def.h:194
tools_GLboolean(* tools_glIsEnabled_func)(tools_GLenum)
Definition gl2ps_def.h:188
void free(voidpf ptr)
voidp malloc(uInt size)
const char * name(G4int ptype)