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

Last change on this file since 953 was 950, checked in by garnier, 17 years ago

bug fix in glReadPixels

  • Property svn:mime-type set to text/cpp
File size: 22.6 KB
RevLine 
[529]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//
[941]27// $Id: G4OpenGLViewer.cc,v 1.50 2009/03/05 16:36:13 lgarnier Exp $
[873]28// GEANT4 tag $Name: $
[529]29//
30//
31// Andrew Walkden 27th March 1996
32// OpenGL view - opens window, hard copy, etc.
33
34#ifdef G4VIS_BUILD_OPENGL_DRIVER
35
36#include "G4ios.hh"
37#include "G4OpenGLViewer.hh"
38#include "G4OpenGLSceneHandler.hh"
39#include "G4OpenGLTransform3D.hh"
[923]40#include "G4OpenGL2PSAction.hh"
[529]41
42#include "G4Scene.hh"
43#include "G4VisExtent.hh"
44#include "G4LogicalVolume.hh"
45#include "G4VSolid.hh"
46#include "G4Point3D.hh"
47#include "G4Normal3D.hh"
48#include "G4Plane3D.hh"
[593]49#include "G4AttHolder.hh"
50#include "G4AttCheck.hh"
[918]51
[923]52// GL2PS
53#include "Geant4_gl2ps.h"
54
[593]55#include <sstream>
[529]56
57G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
58G4VViewer (scene, -1),
[916]59fPrintFilename ("G4OpenGL.eps"),
60fPrintColour (true),
61fVectoredPs (true),
[941]62fPrintSizeX(0),
63fPrintSizeY(0),
[593]64fOpenGLSceneHandler(scene),
[529]65background (G4Colour(0.,0.,0.)),
66transparency_enabled (true),
67antialiasing_enabled (false),
68haloing_enabled (false),
[789]69fStartTime(-DBL_MAX),
70fEndTime(DBL_MAX),
[529]71fFadeFactor(0.),
72fDisplayHeadTime(false),
73fDisplayHeadTimeX(-0.9),
74fDisplayHeadTimeY(-0.9),
75fDisplayHeadTimeSize(24.),
76fDisplayHeadTimeRed(0.),
77fDisplayHeadTimeGreen(1.),
78fDisplayHeadTimeBlue(1.),
79fDisplayLightFront(false),
80fDisplayLightFrontX(0.),
81fDisplayLightFrontY(0.),
82fDisplayLightFrontZ(0.),
83fDisplayLightFrontT(0.),
84fDisplayLightFrontRed(0.),
85fDisplayLightFrontGreen(1.),
[916]86fDisplayLightFrontBlue(0.),
87fPointSize (0)
[529]88{
89 // Make changes to view parameters for OpenGL...
90 fVP.SetAutoRefresh(true);
91 fDefaultVP.SetAutoRefresh(true);
[897]92 fWinSize_x = fVP.GetWindowSizeHintX();
93 fWinSize_y = fVP.GetWindowSizeHintY();
[529]94
[921]95 fGL2PSAction = new G4OpenGL2PSAction();
96
[529]97 // glClearColor (0.0, 0.0, 0.0, 0.0);
98 // glClearDepth (1.0);
99 // glDisable (GL_BLEND);
100 // glDisable (GL_LINE_SMOOTH);
101 // glDisable (GL_POLYGON_SMOOTH);
102
103}
104
105G4OpenGLViewer::~G4OpenGLViewer () {}
106
107void G4OpenGLViewer::InitializeGLView ()
108{
109 glClearColor (0.0, 0.0, 0.0, 0.0);
110 glClearDepth (1.0);
111 glDisable (GL_BLEND);
112 glDisable (GL_LINE_SMOOTH);
113 glDisable (GL_POLYGON_SMOOTH);
114}
115
116void G4OpenGLViewer::ClearView () {
[948]117 printf("G4OpenGLViewer::ClearView\n");
[529]118 glClearColor (background.GetRed(),
119 background.GetGreen(),
120 background.GetBlue(),
121 1.);
122 glClearDepth (1.0);
123 //Below line does not compile with Mesa includes.
124 //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
125 glClear (GL_COLOR_BUFFER_BIT);
126 glClear (GL_DEPTH_BUFFER_BIT);
127 glClear (GL_STENCIL_BUFFER_BIT);
128 glFlush ();
129}
130
[906]131
132/**
133 * Set the viewport of the scene
[945]134 * MAXIMUM SIZE is :
135 * GLint dims[2];
136 * glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
[906]137 */
138void G4OpenGLViewer::ResizeGLView()
139{
[949]140 printf("G4OpenGLViewer::ResizeGLView %d %d\n",fWinSize_x,fWinSize_y);
[945]141 // Check size
142 GLint dims[2];
143 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
144 if (fWinSize_x > (unsigned)dims[0]) {
145 G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<dims[0] <<" is resize to "<< dims[0] << G4endl;
146 fWinSize_x = dims[0];
147 }
148 if (fWinSize_y > (unsigned)dims[1]) {
149 G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<dims[0] <<" is resize to "<< dims[1] << G4endl;
150 fWinSize_y = dims[1];
151 }
[949]152 GLsizei side = fWinSize_x;
[906]153 if (fWinSize_y < fWinSize_x) side = fWinSize_y;
[949]154
155 // SPECIAL CASE if fWinSize_x is even (69 for example)
156 // Ex : X: 69 Y: 26
157 // side = 26
158 // width / 2 = 21,5
159 // height / 2 = 0
160 // Should be fixed to closed : 21 0 for ex
161 // Then size must by change to :
162 // X:68 Y: 26
163
164 // SPECIAL CASE
165 if ((fWinSize_x - side)%2) {
[950]166 // fWinSize_x --;
167
168 side = fWinSize_x;
169 if (fWinSize_y < fWinSize_x) side = fWinSize_y;
[949]170 }
171 if ((fWinSize_y - side)%2) {
[950]172 // fWinSize_y --;
173
174 side = fWinSize_x;
175 if (fWinSize_y < fWinSize_x) side = fWinSize_y;
[949]176 }
177
[950]178 GLint X = (fWinSize_x - side) / 2;
179 GLint Y = (fWinSize_y - side) / 2;
[949]180
[950]181 printf("G4OpenGLViewer::ResizeGLView X:%d Y:%d W:%d H:%d --side%d\n",(fWinSize_x - side) / 2,(fWinSize_y - side) / 2,fWinSize_x,fWinSize_y,side);
182 glViewport(X, Y, side, side);
183 // glViewport(0, 0, fWinSize_x,fWinSize_y);
184
185
[906]186}
187
188
[529]189void G4OpenGLViewer::SetView () {
[858]190
191 if (!fSceneHandler.GetScene()) {
[908]192 G4cerr << "G4OpenGLStoredViewer: Creating a Viewer without a scene is not allowed. \nPlease use /vis/scene/create before /vis/open/.... "
[858]193 << G4endl;
194 return;
195 }
[529]196 // Calculates view representation based on extent of object being
197 // viewed and (initial) viewpoint. (Note: it can change later due
198 // to user interaction via visualization system's GUI.)
199
200 // Lighting.
201 GLfloat lightPosition [4];
202 lightPosition [0] = fVP.GetActualLightpointDirection().x();
203 lightPosition [1] = fVP.GetActualLightpointDirection().y();
204 lightPosition [2] = fVP.GetActualLightpointDirection().z();
205 lightPosition [3] = 0.;
206 // Light position is "true" light direction, so must come after gluLookAt.
207 GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.};
208 GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.};
209 glEnable (GL_LIGHT0);
210 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient);
211 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse);
212
213 // Get radius of scene, etc.
214 // Note that this procedure properly takes into account zoom, dolly and pan.
215 const G4Point3D targetPoint
216 = fSceneHandler.GetScene()->GetStandardTargetPoint()
217 + fVP.GetCurrentTargetPoint ();
218 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
219 if(radius<=0.) radius = 1.;
220 const G4double cameraDistance = fVP.GetCameraDistance (radius);
221 const G4Point3D cameraPosition =
222 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
[906]223 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
224 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
[529]225 const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius);
226 const GLdouble left = -right;
227 const GLdouble bottom = left;
228 const GLdouble top = right;
229
[906]230 // FIXME
231 ResizeGLView();
[908]232 //SHOULD SetWindowsSizeHint()...
[906]233
[529]234 glMatrixMode (GL_PROJECTION); // set up Frustum.
235 glLoadIdentity();
236
[906]237 const G4Vector3D scaleFactor = fVP.GetScaleFactor();
238 glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
[529]239
240 if (fVP.GetFieldHalfAngle() == 0.) {
241 glOrtho (left, right, bottom, top, pnear, pfar);
242 }
243 else {
244 glFrustum (left, right, bottom, top, pnear, pfar);
[908]245 }
[906]246
[529]247 glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
248 glLoadIdentity();
249
250 const G4Normal3D& upVector = fVP.GetUpVector ();
251 G4Point3D gltarget;
252 if (cameraDistance > 1.e-6 * radius) {
253 gltarget = targetPoint;
254 }
255 else {
256 gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit();
257 }
258
259 const G4Point3D& pCamera = cameraPosition; // An alias for brevity.
260 gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
261 gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
262 upVector.x(), upVector.y(), upVector.z()); // Up vector.
[906]263
[529]264 // Light position is "true" light direction, so must come after gluLookAt.
265 glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
266
267 // OpenGL no longer seems to reconstruct clipped edges, so, when the
268 // BooleanProcessor is up to it, abandon this and use generic
269 // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron. Also,
270 // force kernel visit on change of clipping plane in
271 // G4OpenGLStoredViewer::CompareForKernelVisit.
272 if (fVP.IsSection () ) { // pair of back to back clip planes.
273 const G4Plane3D& s = fVP.GetSectionPlane ();
274 double sArray[4];
275 sArray[0] = s.a();
276 sArray[1] = s.b();
277 sArray[2] = s.c();
278 sArray[3] = s.d() + radius * 1.e-05;
279 glClipPlane (GL_CLIP_PLANE0, sArray);
280 glEnable (GL_CLIP_PLANE0);
281 sArray[0] = -s.a();
282 sArray[1] = -s.b();
283 sArray[2] = -s.c();
284 sArray[3] = -s.d() + radius * 1.e-05;
285 glClipPlane (GL_CLIP_PLANE1, sArray);
286 glEnable (GL_CLIP_PLANE1);
287 } else {
288 glDisable (GL_CLIP_PLANE0);
289 glDisable (GL_CLIP_PLANE1);
290 }
291
292 const G4Planes& cutaways = fVP.GetCutawayPlanes();
293 size_t nPlanes = cutaways.size();
294 if (fVP.IsCutaway() &&
295 fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection &&
296 nPlanes > 0) {
297 double a[4];
298 a[0] = cutaways[0].a();
299 a[1] = cutaways[0].b();
300 a[2] = cutaways[0].c();
301 a[3] = cutaways[0].d();
302 glClipPlane (GL_CLIP_PLANE2, a);
303 glEnable (GL_CLIP_PLANE2);
304 if (nPlanes > 1) {
305 a[0] = cutaways[1].a();
306 a[1] = cutaways[1].b();
307 a[2] = cutaways[1].c();
308 a[3] = cutaways[1].d();
309 glClipPlane (GL_CLIP_PLANE3, a);
310 glEnable (GL_CLIP_PLANE3);
311 }
312 if (nPlanes > 2) {
313 a[0] = cutaways[2].a();
314 a[1] = cutaways[2].b();
315 a[2] = cutaways[2].c();
316 a[3] = cutaways[2].d();
317 glClipPlane (GL_CLIP_PLANE4, a);
318 glEnable (GL_CLIP_PLANE4);
319 }
320 } else {
321 glDisable (GL_CLIP_PLANE2);
322 glDisable (GL_CLIP_PLANE3);
323 glDisable (GL_CLIP_PLANE4);
324 }
325
326 // Background.
327 background = fVP.GetBackgroundColour ();
328
329}
330
331void G4OpenGLViewer::HaloingFirstPass () {
332
333 //To perform haloing, first Draw all information to the depth buffer
334 //alone, using a chunky line width, and then Draw all info again, to
335 //the colour buffer, setting a thinner line width an the depth testing
336 //function to less than or equal, so if two lines cross, the one
337 //passing behind the other will not pass the depth test, and so not
338 //get rendered either side of the infront line for a short distance.
339
340 //First, disable writing to the colo(u)r buffer...
341 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
342
343 //Now enable writing to the depth buffer...
344 glDepthMask (GL_TRUE);
345 glDepthFunc (GL_LESS);
346 glClearDepth (1.0);
347
348 //Finally, set the line width to something wide...
349 glLineWidth (3.0);
350
351}
352
353void G4OpenGLViewer::HaloingSecondPass () {
354
355 //And finally, turn the colour buffer back on with a sesible line width...
356 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
357 glDepthFunc (GL_LEQUAL);
358 glLineWidth (1.0);
359
360}
361
[593]362void G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
363{
364 //G4cout << "X: " << x << ", Y: " << y << G4endl;
365 const G4int BUFSIZE = 512;
366 GLuint selectBuffer[BUFSIZE];
367 glSelectBuffer(BUFSIZE, selectBuffer);
368 glRenderMode(GL_SELECT);
369 glInitNames();
370 glPushName(0);
371 glMatrixMode(GL_PROJECTION);
372 G4double currentProjectionMatrix[16];
373 glGetDoublev(GL_PROJECTION_MATRIX, currentProjectionMatrix);
374 glPushMatrix();
375 glLoadIdentity();
376 GLint viewport[4];
377 glGetIntegerv(GL_VIEWPORT, viewport);
378 // Define 5x5 pixel pick area
379 gluPickMatrix(x, viewport[3] - y, 5., 5., viewport);
380 glMultMatrixd(currentProjectionMatrix);
381 glMatrixMode(GL_MODELVIEW);
382 DrawView();
383 GLint hits = glRenderMode(GL_RENDER);
384 if (hits < 0)
385 G4cout << "Too many hits. Zoom in to reduce overlaps." << G4cout;
386 else if (hits > 0) {
387 //G4cout << hits << " hit(s)" << G4endl;
388 GLuint* p = selectBuffer;
389 for (GLint i = 0; i < hits; ++i) {
390 GLuint nnames = *p++;
391 *p++; //OR GLuint zmin = *p++;
392 *p++; //OR GLuint zmax = *p++;
393 //G4cout << "Hit " << i << ": " << nnames << " names"
394 // << "\nzmin: " << zmin << ", zmax: " << zmax << G4endl;
395 for (GLuint j = 0; j < nnames; ++j) {
396 GLuint name = *p++;
397 //G4cout << "Name " << j << ": PickName: " << name << G4endl;
398 std::map<GLuint, G4AttHolder*>::iterator iter =
399 fOpenGLSceneHandler.fPickMap.find(name);
400 if (iter != fOpenGLSceneHandler.fPickMap.end()) {
401 G4AttHolder* attHolder = iter->second;
402 if(attHolder && attHolder->GetAttDefs().size()) {
403 for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
404 G4cout << G4AttCheck(attHolder->GetAttValues()[i],
405 attHolder->GetAttDefs()[i]);
406 }
407 }
408 }
409 }
410 G4cout << G4endl;
411 }
412 }
413 glMatrixMode(GL_PROJECTION);
414 glPopMatrix();
415 glMatrixMode(GL_MODELVIEW);
416}
417
418
[754]419
[593]420
[914]421GLubyte* G4OpenGLViewer::grabPixels (int inColor, unsigned int width, unsigned int height) {
422
423 GLubyte* buffer;
424 GLint swapbytes, lsbfirst, rowlength;
425 GLint skiprows, skippixels, alignment;
426 GLenum format;
427 int size;
428
429 if (inColor) {
430 format = GL_RGB;
431 size = width*height*3;
432 } else {
433 format = GL_LUMINANCE;
434 size = width*height*1;
435 }
436
437 buffer = new GLubyte[size];
438 if (buffer == NULL)
439 return NULL;
440
441 glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
442 glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
443 glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
444
445 glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
446 glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
447 glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
448
449 glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
450 glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
451 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
452
453 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
454 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
455 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
456
457 glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
458
459 glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
460 glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
461 glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
462
463 glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
464 glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
465 glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
466
467 return buffer;
468}
469
[941]470void G4OpenGLViewer::printEPS() {
471 bool res;
[942]472#ifdef G4DEBUG_VIS_OGL
473 printf("G4OpenGLViewer::printEPS file:%s Vec:%d\n",fPrintFilename.c_str(),fVectoredPs);
474#endif
[941]475 if (fVectoredPs) {
476 res = printVectoredEPS();
477 } else {
478 res = printNonVectoredEPS();
479 }
480 if (res == false) {
481 G4cerr << "Error while saving file... "<<fPrintFilename.c_str()<< G4endl;
482 } else {
483 G4cout << "File "<<fPrintFilename.c_str()<<" has been saved " << G4endl;
484 }
485}
[914]486
[941]487bool G4OpenGLViewer::printVectoredEPS() {
488 return printGl2PS();
489}
490
491bool G4OpenGLViewer::printNonVectoredEPS () {
492
493 int width = 0;
494 int height = 0;
495
496 if (fPrintSizeX == 0) {
497 width = fWinSize_x;
498 } else {
499 width = fPrintSizeX;
500 }
501 if (fPrintSizeY == 0) {
502 height = fWinSize_y;
503 } else {
504 height = fPrintSizeY;
505 }
506
[942]507#ifdef G4DEBUG_VIS_OGL
508 printf("G4OpenGLViewer::printNonVectoredEPS file:%s Vec:%d X:%d Y:%d col:%d\n",fPrintFilename.c_str(),fVectoredPs,width,height,fPrintColour);
509#endif
[914]510 FILE* fp;
511 GLubyte* pixels;
512 GLubyte* curpix;
513 int components, pos, i;
514
[941]515 pixels = grabPixels (fPrintColour, width, height);
[914]516
[941]517 if (pixels == NULL) {
518 G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
519 return false;
520 }
521 if (fPrintColour) {
[914]522 components = 3;
523 } else {
524 components = 1;
525 }
526
[938]527 fp = fopen (fPrintFilename.c_str(), "w");
[914]528 if (fp == NULL) {
[941]529 G4cerr << "Can't open filename " << fPrintFilename.c_str() << G4endl;
530 return false;
[914]531 }
532
533 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
[938]534 fprintf (fp, "%%%%Title: %s\n", fPrintFilename.c_str());
[914]535 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
536 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
537 fprintf (fp, "%%%%EndComments\n");
538 fprintf (fp, "gsave\n");
539 fprintf (fp, "/bwproc {\n");
540 fprintf (fp, " rgbproc\n");
541 fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
542 fprintf (fp, " 5 -1 roll {\n");
543 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
544 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
545 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
546 fprintf (fp, " { 2 1 roll } ifelse\n");
547 fprintf (fp, " }forall\n");
548 fprintf (fp, " pop pop pop\n");
549 fprintf (fp, "} def\n");
550 fprintf (fp, "systemdict /colorimage known not {\n");
551 fprintf (fp, " /colorimage {\n");
552 fprintf (fp, " pop\n");
553 fprintf (fp, " pop\n");
554 fprintf (fp, " /rgbproc exch def\n");
555 fprintf (fp, " { bwproc } image\n");
556 fprintf (fp, " } def\n");
557 fprintf (fp, "} if\n");
558 fprintf (fp, "/picstr %d string def\n", width * components);
559 fprintf (fp, "%d %d scale\n", width, height);
560 fprintf (fp, "%d %d %d\n", width, height, 8);
561 fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
562 fprintf (fp, "{currentfile picstr readhexstring pop}\n");
563 fprintf (fp, "false %d\n", components);
564 fprintf (fp, "colorimage\n");
565
566 curpix = (GLubyte*) pixels;
567 pos = 0;
568 for (i = width*height*components; i>0; i--) {
569 fprintf (fp, "%02hx ", *(curpix++));
570 if (++pos >= 32) {
571 fprintf (fp, "\n");
572 pos = 0;
573 }
574 }
575 if (pos)
576 fprintf (fp, "\n");
577
578 fprintf (fp, "grestore\n");
579 fprintf (fp, "showpage\n");
580 delete pixels;
581 fclose (fp);
[941]582
583 // Reset for next time (useful is size change)
584 fPrintSizeX = 0;
585 fPrintSizeY = 0;
586
587 return true;
[914]588}
589
[918]590
[941]591bool G4OpenGLViewer::printGl2PS() {
[918]592
[941]593 int width = 0;
594 int height = 0;
595
596 if (fPrintSizeX == 0) {
597 width = fWinSize_x;
598 } else {
599 width = fPrintSizeX;
600 }
601 if (fPrintSizeY == 0) {
602 height = fWinSize_y;
603 } else {
604 height = fPrintSizeY;
605 }
606
[938]607 if (!fGL2PSAction) return false;
[929]608
[945]609
[938]610 fGL2PSAction->setFileName(fPrintFilename.c_str());
611 // try to resize
612 int X = fWinSize_x;
613 int Y = fWinSize_y;
[929]614
[938]615 fWinSize_x = width;
616 fWinSize_y = height;
[945]617
[938]618 ResizeGLView();
[921]619 if (fGL2PSAction->enableFileWriting()) {
[945]620
[948]621 // By default, we choose the line width (trajectories...)
622 fGL2PSAction->setLineWidth(1);
623 // By default, we choose the point size (markers...)
624 fGL2PSAction->setPointSize(2);
[945]625
[931]626 DrawView ();
[921]627 fGL2PSAction->disableFileWriting();
628 }
[929]629
[938]630 fWinSize_x = X;
631 fWinSize_y = Y;
632 ResizeGLView();
[929]633
[941]634 // Reset for next time (useful is size change)
635 fPrintSizeX = 0;
636 fPrintSizeY = 0;
637
[938]638 return true;
[918]639}
640
[712]641GLdouble G4OpenGLViewer::getSceneNearWidth()
642{
643 const G4Point3D targetPoint
644 = fSceneHandler.GetScene()->GetStandardTargetPoint()
645 + fVP.GetCurrentTargetPoint ();
646 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
647 if(radius<=0.) radius = 1.;
648 const G4double cameraDistance = fVP.GetCameraDistance (radius);
649 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
650 return 2 * fVP.GetFrontHalfHeight (pnear, radius);
651}
652
653GLdouble G4OpenGLViewer::getSceneFarWidth()
654{
655 const G4Point3D targetPoint
656 = fSceneHandler.GetScene()->GetStandardTargetPoint()
657 + fVP.GetCurrentTargetPoint ();
658 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
659 if(radius<=0.) radius = 1.;
660 const G4double cameraDistance = fVP.GetCameraDistance (radius);
661 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
662 const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
663 return 2 * fVP.GetFrontHalfHeight (pfar, radius);
664}
665
666
667GLdouble G4OpenGLViewer::getSceneDepth()
668{
669 const G4Point3D targetPoint
670 = fSceneHandler.GetScene()->GetStandardTargetPoint()
671 + fVP.GetCurrentTargetPoint ();
672 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
673 if(radius<=0.) radius = 1.;
674 const G4double cameraDistance = fVP.GetCameraDistance (radius);
675 const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
676 return fVP.GetFarDistance (cameraDistance, pnear, radius)- pnear;
677}
678
679
[593]680
[798]681void G4OpenGLViewer::rotateScene(G4double dx, G4double dy,G4double deltaRotation)
682{
683
684 G4Vector3D vp;
685 G4Vector3D up;
686
687 G4Vector3D xprime;
688 G4Vector3D yprime;
689 G4Vector3D zprime;
690
691 G4double delta_alpha;
692 G4double delta_theta;
693
694 G4Vector3D new_vp;
695 G4Vector3D new_up;
696
697 G4double cosalpha;
698 G4double sinalpha;
699
700 G4Vector3D a1;
701 G4Vector3D a2;
702 G4Vector3D delta;
703 G4Vector3D viewPoint;
704
705
706 //phi spin stuff here
707
708 vp = fVP.GetViewpointDirection ().unit ();
709 up = fVP.GetUpVector ().unit ();
710
711 yprime = (up.cross(vp)).unit();
712 zprime = (vp.cross(yprime)).unit();
713
714 if (fVP.GetLightsMoveWithCamera()) {
715 delta_alpha = dy * deltaRotation;
716 delta_theta = -dx * deltaRotation;
717 } else {
718 delta_alpha = -dy * deltaRotation;
719 delta_theta = dx * deltaRotation;
720 }
721
722 delta_alpha *= deg;
723 delta_theta *= deg;
724
725 new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
726
727 // to avoid z rotation flipping
728 // to allow more than 360° rotation
[847]729
[801]730 const G4Point3D targetPoint
731 = fSceneHandler.GetScene()->GetStandardTargetPoint()
732 + fVP.GetCurrentTargetPoint ();
733 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
734 if(radius<=0.) radius = 1.;
735 const G4double cameraDistance = fVP.GetCameraDistance (radius);
736 const G4Point3D cameraPosition =
737 targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
738
[798]739 if (fVP.GetLightsMoveWithCamera()) {
740 new_up = (new_vp.cross(yprime)).unit();
741 if (new_vp.z()*vp.z() <0) {
742 new_up.set(new_up.x(),-new_up.y(),new_up.z());
743 }
744 } else {
745 new_up = up;
746 if (new_vp.z()*vp.z() <0) {
747 new_up.set(new_up.x(),-new_up.y(),new_up.z());
748 }
749 }
750 fVP.SetUpVector(new_up);
751 ////////////////
752 // Rotates by fixed azimuthal angle delta_theta.
753
754 cosalpha = new_up.dot (new_vp.unit());
755 sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
756 yprime = (new_up.cross (new_vp.unit())).unit ();
757 xprime = yprime.cross (new_up);
758 // Projection of vp on plane perpendicular to up...
759 a1 = sinalpha * xprime;
760 // Required new projection...
761 a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
762 // Required Increment vector...
763 delta = a2 - a1;
764 // So new viewpoint is...
765 viewPoint = new_vp.unit() + delta;
766
767 fVP.SetViewAndLights (viewPoint);
768}
769
[529]770#endif
Note: See TracBrowser for help on using the repository browser.