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