source: trunk/geant4/visualization/OpenGL/old-src/G4OpenGLSceneHandler.cc@ 571

Last change on this file since 571 was 562, checked in by garnier, 18 years ago

r565@mac-90108: laurentgarnier | 2007-08-14 14:18:03 +0200
mise a jour suite au plantage de svk (cheksum error) suite au crash du DD en juin

  • Property svn:mime-type set to text/cpp
File size: 25.3 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4OpenGLSceneHandler.cc,v 1.45 2006/08/30 11:37:34 allison Exp $
28// GEANT4 tag $Name: geant4-08-02-patch-01 $
29//
30//
31// Andrew Walkden 27th March 1996
32// OpenGL stored scene - creates OpenGL display lists.
33// OpenGL immediate scene - draws immediately to buffer
34// (saving space on server).
35
36#ifdef G4VIS_BUILD_OPENGL_DRIVER
37
38// Included here - problems with HP compiler if not before other includes?
39#include "G4NURBS.hh"
40
41// Here follows a special for Mesa, the OpenGL emulator. Does not affect
42// other OpenGL's, as far as I'm aware. John Allison 18/9/96.
43#define CENTERLINE_CLPP /* CenterLine C++ workaround: */
44// Also seems to be required for HP's CC and AIX xlC, at least.
45
46#include "G4OpenGLSceneHandler.hh"
47#include "G4OpenGLViewer.hh"
48#include "G4OpenGLFontBaseStore.hh"
49#include "G4OpenGLTransform3D.hh"
50#include "G4Point3D.hh"
51#include "G4Normal3D.hh"
52#include "G4Transform3D.hh"
53#include "G4Polyline.hh"
54#include "G4Text.hh"
55#include "G4Circle.hh"
56#include "G4Square.hh"
57#include "G4VMarker.hh"
58#include "G4Polyhedron.hh"
59#include "G4VisAttributes.hh"
60#include "G4PhysicalVolumeModel.hh"
61#include "G4VPhysicalVolume.hh"
62#include "G4LogicalVolume.hh"
63#include "G4VSolid.hh"
64#include "G4Scene.hh"
65#include "G4VisExtent.hh"
66
67G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system,
68 G4int id,
69 const G4String& name):
70 G4VSceneHandler (system, id, name)
71{}
72
73G4OpenGLSceneHandler::~G4OpenGLSceneHandler ()
74{
75 ClearStore ();
76}
77
78const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = {
79 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
80 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
81 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
82 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
83 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
84 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
85 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
86 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
87 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
88 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
89 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
90 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
91 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
92 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
93 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
94 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
95};
96
97const G4Polyhedron* G4OpenGLSceneHandler::CreateSectionPolyhedron ()
98{
99 // Clipping done in G4OpenGLViewer::SetView.
100 return 0;
101
102 // But...OpenGL no longer seems to reconstruct clipped edges, so,
103 // when the BooleanProcessor is up to it, abandon this and use
104 // generic clipping in G4VSceneHandler::CreateSectionPolyhedron...
105 // return G4VSceneHandler::CreateSectionPolyhedron();
106}
107
108const G4Polyhedron* G4OpenGLSceneHandler::CreateCutawayPolyhedron ()
109{
110 // Cutaway done in G4OpenGLViewer::SetView.
111 return 0;
112
113 // But...if not, when the BooleanProcessor is up to it...
114 // return G4VSceneHandler::CreateCutawayPolyhedron();
115}
116
117void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
118{
119 G4int nPoints = line.size ();
120 if (nPoints <= 0) return;
121
122 // Note: colour treated in sub-class.
123
124 if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
125 glDisable (GL_DEPTH_TEST);
126 else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
127
128 glDisable (GL_LIGHTING);
129
130 G4double lineWidth = GetLineWidth(line);
131 glLineWidth(lineWidth);
132
133 glBegin (GL_LINE_STRIP);
134 for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
135 G4double x, y, z;
136 x = line[iPoint].x();
137 y = line[iPoint].y();
138 z = line[iPoint].z();
139 glVertex3d (x, y, z);
140 }
141 glEnd ();
142}
143
144void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
145
146 const G4Colour& c = GetTextColour (text); // Picks up default if none.
147 MarkerSizeType sizeType;
148 G4double size = GetMarkerSize (text, sizeType);
149 G4ThreeVector position (text.GetPosition ());
150 G4String textString = text.GetText();
151
152 G4int font_base = G4OpenGLFontBaseStore::GetFontBase(fpViewer,size);
153 if (font_base < 0) {
154 static G4int callCount = 0;
155 ++callCount;
156 if (callCount <= 10 || callCount%100 == 0) {
157 G4cout <<
158 "G4OpenGLSceneHandler::AddPrimitive (const G4Text&) call count "
159 << callCount <<
160 "\n No fonts available."
161 "\n Called with text \""
162 << text.GetText ()
163 << "\"\n at " << position
164 << ", size " << size
165 << ", offsets " << text.GetXOffset () << ", " << text.GetYOffset ()
166 << ", type " << G4int(sizeType)
167 << ", colour " << c
168 << G4endl;
169 }
170 return;
171 }
172 const char* textCString = textString.c_str();
173 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
174 glDisable (GL_DEPTH_TEST);
175 glDisable (GL_LIGHTING);
176
177 glRasterPos3f(position.x(),position.y(),position.z());
178 // No action on offset or layout at present.
179 glPushAttrib(GL_LIST_BIT);
180 glListBase(font_base);
181 glCallLists(strlen(textCString), GL_UNSIGNED_BYTE, (GLubyte *)textCString);
182 glPopAttrib();
183}
184
185void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
186 glEnable (GL_POINT_SMOOTH);
187 AddCircleSquare (circle, 24);
188}
189
190void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
191 glDisable (GL_POINT_SMOOTH);
192 AddCircleSquare (square, 4);
193}
194
195void G4OpenGLSceneHandler::AddCircleSquare
196(const G4VMarker& marker,
197 G4int nSides) {
198
199 // Note: colour treated in sub-class.
200
201 if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
202 glDisable (GL_DEPTH_TEST);
203 else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
204
205 glDisable (GL_LIGHTING);
206
207 G4double lineWidth = GetLineWidth(marker);
208 glLineWidth(lineWidth);
209
210 G4VMarker::FillStyle style = marker.GetFillStyle();
211
212 switch (style) {
213 case G4VMarker::noFill:
214 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
215 break;
216
217 case G4VMarker::hashed:
218 /*
219 G4cout << "Hashed fill style in G4OpenGLSceneHandler."
220 << "\n Not implemented. Using G4VMarker::filled."
221 << G4endl;
222 */
223 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
224 glPolygonStipple (fStippleMaskHashed);
225 // See also:
226 // if (style == G4VMarker::filled || style == G4VMarker::hashed)...
227 // (twice) below.
228 break;
229
230 case G4VMarker::filled:
231 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
232 break;
233
234 default:
235 G4cout << "Unrecognised fill style in G4OpenGLSceneHandler."
236 << "\n Using G4VMarker::filled."
237 << G4endl;
238 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
239 break;
240
241 }
242
243 // A few useful quantities...
244 G4Point3D centre = marker.GetPosition();
245 const G4Vector3D& viewpointDirection =
246 fpViewer -> GetViewParameters().GetViewpointDirection();
247 const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
248 MarkerSizeType sizeType;
249 G4double size = GetMarkerSize(marker, sizeType);
250
251 // Find "size" of marker in world space (but see note below)...
252 G4double worldSize;
253 if (sizeType == world) { // Size specified in world coordinates.
254 worldSize = size;
255 }
256 else { // Size specified in screen (window) coordinates.
257
258 // Find window coordinates of centre...
259 GLdouble modelMatrix[16];
260 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
261 G4double projectionMatrix[16];
262 glGetDoublev (GL_PROJECTION_MATRIX, projectionMatrix);
263 GLint viewport[4];
264 glGetIntegerv(GL_VIEWPORT,viewport);
265 GLdouble winx, winy, winz;
266 gluProject(centre.x(), centre.y(), centre.z(),
267 modelMatrix, projectionMatrix, viewport,
268 &winx, &winy, &winz);
269
270 // Determine ratio window:world...
271 const G4Vector3D inScreen = (up.cross(viewpointDirection)).unit();
272 const G4Vector3D p = centre + inScreen;
273 GLdouble winDx, winDy, winDz;
274 gluProject(p.x(), p.y(), p.z(),
275 modelMatrix, projectionMatrix, viewport,
276 &winDx, &winDy, &winDz);
277 G4double winWorldRatio = std::sqrt(std::pow(winx - winDx, 2) +
278 std::pow(winy - winDy, 2));
279 worldSize = size / winWorldRatio;
280 }
281
282 // Draw...
283 DrawXYPolygon (worldSize, centre, nSides);
284}
285
286/***************************************************
287Note: We have to do it this way round so that when a global
288transformation is applied, such as with /vis/viewer/set/viewpoint,
289the markers follow the world coordinates without having to
290recreate the display lists. The down side is that the markers
291rotate. The only way to avoid this is to play with the modelview
292and projection matrices of OpenGL - which I need to think about.
293For future reference, here is the code to draw in window
294coordinates; its down side is that markers do not follow global
295transformations. Some clever stuff is needed.
296
297 ...
298 // Find window coordinates of centre...
299 GLdouble modelMatrix[16];
300 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
301 G4double projectionMatrix[16];
302 glGetDoublev (GL_PROJECTION_MATRIX, projectionMatrix);
303 GLint viewport[4];
304 glGetIntegerv(GL_VIEWPORT,viewport);
305 GLdouble winx, winy, winz;
306 gluProject(centre.x(), centre.y(), centre.z(),
307 modelMatrix, projectionMatrix, viewport,
308 &winx, &winy, &winz);
309
310 // Find window size...
311 G4double winSize;
312 if (size) { // Size specified in world coordinates.
313 // Determine size in window coordinates...
314 (Note: improve this by using an inScreen vector as above.)
315 GLdouble winx1, winy1, winz1;
316 gluProject(centre.x() + size, centre.y() + size, centre.z() + size,
317 modelMatrix, projectionMatrix, viewport,
318 &winx1, &winy1, &winz1);
319 winSize = std::sqrt((std::pow(winx - winx1, 2) +
320 std::pow(winy - winy1, 2) +
321 std::pow(winz - winz1, 2)) / 3.);
322 }
323 else {
324 winSize = scale *
325 userSpecified ? marker.GetScreenSize() : def.GetScreenSize();
326 }
327
328 // Prepare to draw in window coordinates...
329 glMatrixMode (GL_PROJECTION);
330 glPushMatrix();
331 glLoadIdentity();
332 gluOrtho2D(GLdouble(viewport[0]),
333 GLdouble(viewport[0] + viewport[2]),
334 GLdouble(viewport[1]),
335 GLdouble(viewport[1] + viewport[3]));
336 glMatrixMode (GL_MODELVIEW);
337 glPushMatrix();
338 glLoadIdentity();
339
340 // Draw in window coordinates...
341 DrawScreenPolygon (winSize, G4Point3D(winx, winy, winz), nSides);
342
343 // Re-instate matrices...
344 glMatrixMode (GL_PROJECTION);
345 glPopMatrix();
346 glMatrixMode (GL_MODELVIEW);
347 glPopMatrix();
348 ...
349}
350
351void G4OpenGLSceneHandler::DrawScreenPolygon
352(G4double size,
353 const G4Point3D& centre,
354 G4int nSides) {
355 glBegin (GL_POLYGON);
356 const G4double dPhi = twopi / nSides;
357 const G4double r = size / 2.;
358 G4double phi;
359 G4int i;
360 for (i = 0, phi = -dPhi / 2.; i < nSides; i++, phi += dPhi) {
361 G4double x, y, z;
362 x = centre.x() + r * std::cos(phi);
363 y = centre.y() + r * std::sin(phi);
364 z = centre.z();
365 glVertex3d (x, y, z);
366 }
367 glEnd ();
368}
369**********************************************/
370
371void G4OpenGLSceneHandler::DrawXYPolygon
372(G4double size,
373 const G4Point3D& centre,
374 G4int nSides) {
375 const G4Vector3D& viewpointDirection =
376 fpViewer -> GetViewParameters().GetViewpointDirection();
377 const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
378 const G4double dPhi = twopi / nSides;
379 const G4double radius = size / 2.;
380 G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
381 G4double phi;
382 G4int i;
383 glBegin (GL_POLYGON);
384 for (i = 0, phi = 0.; i < nSides; i++, phi += dPhi) {
385 G4Vector3D r = start; r.rotate(phi, viewpointDirection);
386 G4Vector3D p = centre + r;
387 glVertex3d (p.x(), p.y(), p.z());
388 }
389 glEnd ();
390}
391
392//Method for handling G4Polyhedron objects for drawing solids.
393void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
394
395 // Assume all facets are planar convex quadrilaterals.
396 // Draw each facet individually
397
398 if (polyhedron.GetNoFacets() == 0) return;
399
400 // Get vis attributes - pick up defaults if none.
401 const G4VisAttributes* pVA =
402 fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
403
404 // Get view parameters that the user can force through the vis
405 // attributes, thereby over-riding the current view parameter.
406 G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
407
408 //Get colour, etc...
409 G4bool transparency_enabled = true;
410 G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
411 if (pViewer) transparency_enabled = pViewer->transparency_enabled;
412 const G4Colour& c = GetColour (polyhedron);
413 GLfloat materialColour [4];
414 materialColour [0] = c.GetRed ();
415 materialColour [1] = c.GetGreen ();
416 materialColour [2] = c.GetBlue ();
417 if (transparency_enabled) {
418 materialColour [3] = c.GetAlpha ();
419 } else {
420 materialColour [3] = 1.;
421 }
422
423 G4double lineWidth = GetLineWidth(polyhedron);
424 glLineWidth(lineWidth);
425
426 GLfloat clear_colour[4];
427 glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
428
429 G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
430
431 G4bool clipping = pViewer->fVP.IsSection() || pViewer->fVP.IsCutaway();
432
433 switch (drawing_style) {
434 case (G4ViewParameters::hlhsr):
435 // Set up as for hidden line removal but paint polygon faces later...
436 case (G4ViewParameters::hlr):
437 glEnable (GL_STENCIL_TEST);
438 // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
439 // The procedure below leaves it clear.
440 glStencilFunc (GL_ALWAYS, 0, 1);
441 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
442 glEnable (GL_DEPTH_TEST);
443 glDepthFunc (GL_LEQUAL);
444 if (materialColour[3] < 1.) {
445 // Transparent...
446 glDisable (GL_CULL_FACE);
447 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
448 } else {
449 // Opaque...
450 if (clipping) {
451 glDisable (GL_CULL_FACE);
452 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
453 } else {
454 glEnable (GL_CULL_FACE);
455 glCullFace (GL_BACK);
456 glPolygonMode (GL_FRONT, GL_LINE);
457 }
458 }
459 glDisable (GL_LIGHTING);
460 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
461 break;
462 case (G4ViewParameters::hsr):
463 glEnable (GL_DEPTH_TEST);
464 glDepthFunc (GL_LEQUAL);
465 if (materialColour[3] < 1.) {
466 // Transparent...
467 glDepthMask (0); // Make depth buffer read-only.
468 glDisable (GL_CULL_FACE);
469 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
470 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, materialColour);
471 } else {
472 // Opaque...
473 glDepthMask (1); // Make depth buffer writable (default).
474 if (clipping) {
475 glDisable (GL_CULL_FACE);
476 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
477 } else {
478 glEnable (GL_CULL_FACE);
479 glCullFace (GL_BACK);
480 glPolygonMode (GL_FRONT, GL_FILL);
481 }
482 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
483 }
484 glEnable (GL_LIGHTING);
485 break;
486 case (G4ViewParameters::wireframe):
487 default:
488 glEnable (GL_DEPTH_TEST);
489 glDepthFunc (GL_LEQUAL); //??? was GL_ALWAYS
490 glDisable (GL_CULL_FACE);
491 glDisable (GL_LIGHTING);
492 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
493 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
494 break;
495 }
496
497 //Loop through all the facets...
498 glBegin (GL_QUADS);
499 G4bool notLastFace;
500 do {
501
502 //First, find vertices, edgeflags and normals and note "not last facet"...
503 G4Point3D vertex[4];
504 G4int edgeFlag[4];
505 G4Normal3D normals[4];
506 G4int n;
507 notLastFace = polyhedron.GetNextFacet(n, vertex, edgeFlag, normals);
508
509 //Loop through the four edges of each G4Facet...
510 G4int edgeCount = 0;
511 for(edgeCount = 0; edgeCount < n; ++edgeCount) {
512 // Check to see if edge is visible or not...
513 if (isAuxEdgeVisible) {
514 edgeFlag[edgeCount] = 1;
515 }
516 if (edgeFlag[edgeCount] > 0) {
517 glEdgeFlag (GL_TRUE);
518 } else {
519 glEdgeFlag (GL_FALSE);
520 }
521 glNormal3d (normals[edgeCount].x(),
522 normals[edgeCount].y(),
523 normals[edgeCount].z());
524 glVertex3d (vertex[edgeCount].x(),
525 vertex[edgeCount].y(),
526 vertex[edgeCount].z());
527 }
528 // HepPolyhedron produces triangles too; in that case add an extra
529 // vertex identical to first...
530 if (n == 3) {
531 edgeCount = 3;
532 normals[edgeCount] = normals[0];
533 vertex[edgeCount] = vertex[0];
534 edgeFlag[edgeCount] = -1;
535 glEdgeFlag (GL_FALSE);
536 glNormal3d (normals[edgeCount].x(),
537 normals[edgeCount].y(),
538 normals[edgeCount].z());
539 glVertex3d (vertex[edgeCount].x(),
540 vertex[edgeCount].y(),
541 vertex[edgeCount].z());
542 }
543 // Trap situation where number of edges is > 4...
544 if (n > 4) {
545 G4cerr <<
546 "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING";
547 G4PhysicalVolumeModel* pPVModel =
548 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
549 if (pPVModel) {
550 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
551 G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
552 G4cerr <<
553 "\n Volume " << pCurrentPV->GetName() <<
554 ", Solid " << pCurrentLV->GetSolid()->GetName() <<
555 " (" << pCurrentLV->GetSolid()->GetEntityType();
556 }
557 G4cerr<<
558 "\n G4Polyhedron facet with " << n << " edges" << G4endl;
559 }
560
561 // Do it all over again (twice) for hlr...
562 if (drawing_style == G4ViewParameters::hlr ||
563 drawing_style == G4ViewParameters::hlhsr) {
564
565 glEnd (); // Placed here to balance glBegin above, allowing GL
566 // state changes below, then glBegin again. Avoids
567 // having glBegin/End pairs *inside* loop in the more
568 // usual case of no hidden line removal.
569
570 // Draw through stencil...
571 glStencilFunc (GL_EQUAL, 0, 1);
572 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
573 if (drawing_style == G4ViewParameters::hlhsr) {
574 glEnable (GL_LIGHTING);
575 }
576 glEnable (GL_DEPTH_TEST);
577 glDepthFunc (GL_LEQUAL);
578 if (materialColour[3] < 1.) {
579 // Transparent...
580 glDepthMask (0); // Make depth buffer read-only.
581 glDisable (GL_CULL_FACE);
582 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
583 } else {
584 // Opaque...
585 glDepthMask (1); // Make depth buffer writable (default).
586 if (clipping) {
587 glDisable (GL_CULL_FACE);
588 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
589 } else {
590 glEnable (GL_CULL_FACE);
591 glCullFace (GL_BACK);
592 glPolygonMode (GL_FRONT, GL_FILL);
593 }
594 }
595 GLfloat* painting_colour;
596 if (drawing_style == G4ViewParameters::hlr) {
597 if (materialColour[3] < 1.) {
598 // Transparent - don't paint...
599 goto end_of_drawing_through_stencil;
600 }
601 painting_colour = clear_colour;
602 } else { // drawing_style == G4ViewParameters::hlhsr
603 painting_colour = materialColour;
604 }
605 if (materialColour[3] < 1.) {
606 // Transparent...
607 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
608 } else {
609 // Opaque...
610 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
611 }
612 glColor4fv (painting_colour);
613 glBegin (GL_QUADS);
614 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
615 if (edgeFlag[edgeCount] > 0) {
616 glEdgeFlag (GL_TRUE);
617 } else {
618 glEdgeFlag (GL_FALSE);
619 }
620 glNormal3d (normals[edgeCount].x(),
621 normals[edgeCount].y(),
622 normals[edgeCount].z());
623 glVertex3d (vertex[edgeCount].x(),
624 vertex[edgeCount].y(),
625 vertex[edgeCount].z());
626 }
627 glEnd ();
628 end_of_drawing_through_stencil:
629
630 // and once more to reset the stencil bits...
631 glStencilFunc (GL_ALWAYS, 0, 1);
632 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
633 glDepthFunc (GL_LEQUAL); // to make sure line gets drawn.
634 if (materialColour[3] < 1.) {
635 // Transparent...
636 glDisable (GL_CULL_FACE);
637 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
638 } else {
639 // Opaque...
640 if (clipping) {
641 glDisable (GL_CULL_FACE);
642 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
643 } else {
644 glEnable (GL_CULL_FACE);
645 glCullFace (GL_BACK);
646 glPolygonMode (GL_FRONT, GL_LINE);
647 }
648 }
649 glDisable (GL_LIGHTING);
650 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
651 glBegin (GL_QUADS);
652 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
653 if (edgeFlag[edgeCount] > 0) {
654 glEdgeFlag (GL_TRUE);
655 } else {
656 glEdgeFlag (GL_FALSE);
657 }
658 glNormal3d (normals[edgeCount].x(),
659 normals[edgeCount].y(),
660 normals[edgeCount].z());
661 glVertex3d (vertex[edgeCount].x(),
662 vertex[edgeCount].y(),
663 vertex[edgeCount].z());
664 }
665 glEnd ();
666 glDepthFunc (GL_LEQUAL); // Revert for next facet.
667 glBegin (GL_QUADS); // Ready for next facet. GL
668 // says it ignores incomplete
669 // quadrilaterals, so final empty
670 // glBegin/End sequence should be OK.
671 }
672 } while (notLastFace);
673
674 glEnd ();
675 glDisable (GL_STENCIL_TEST); // Revert to default for next primitive.
676 glDepthMask (1); // Revert to default for next primitive.
677}
678
679//Method for handling G4NURBS objects for drawing solids.
680//Knots and Ctrl Pnts MUST be arrays of GLfloats.
681void G4OpenGLSceneHandler::AddPrimitive (const G4NURBS& nurb) {
682
683 GLUnurbsObj *gl_nurb;
684 gl_nurb = gluNewNurbsRenderer ();
685
686 GLfloat *u_knot_array, *u_knot_array_ptr;
687 u_knot_array = u_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::U)];
688 G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
689 while (u_iterator.pick (u_knot_array_ptr++));
690
691 GLfloat *v_knot_array, *v_knot_array_ptr;
692 v_knot_array = v_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::V)];
693 G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
694 while (v_iterator.pick (v_knot_array_ptr++));
695
696 GLfloat *ctrl_pnt_array, *ctrl_pnt_array_ptr;
697 ctrl_pnt_array = ctrl_pnt_array_ptr =
698 new GLfloat [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC];
699 G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
700 while (c_p_iterator.pick (ctrl_pnt_array_ptr++));
701
702 // Get vis attributes - pick up defaults if none.
703 const G4VisAttributes* pVA =
704 fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
705
706 // Get view parameters that the user can force through the vis
707 // attributes, thereby over-riding the current view parameter.
708 G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
709 //G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
710
711 //Get colour, etc..
712 const G4Colour& c = pVA -> GetColour ();
713
714 switch (drawing_style) {
715
716 case (G4ViewParameters::hlhsr):
717 // G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
718 // << "Using hidden surface removal." << G4endl;
719 case (G4ViewParameters::hsr):
720 {
721 glEnable (GL_LIGHTING);
722 glEnable (GL_DEPTH_TEST);
723 glEnable (GL_AUTO_NORMAL);
724 glEnable (GL_NORMALIZE);
725 gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_FILL);
726 gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
727 GLfloat materialColour [4];
728 materialColour [0] = c.GetRed ();
729 materialColour [1] = c.GetGreen ();
730 materialColour [2] = c.GetBlue ();
731 materialColour [3] = 1.0; // = c.GetAlpha () for transparency -
732 // but see complication in
733 // AddPrimitive(const G4Polyhedron&).
734 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
735 break;
736 }
737 case (G4ViewParameters::hlr):
738 // G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
739 // << "Using wireframe." << G4endl;
740 case (G4ViewParameters::wireframe):
741 default:
742 glDisable (GL_LIGHTING);
743// glDisable (GL_DEPTH_TEST);
744 glEnable (GL_DEPTH_TEST);
745 glDisable (GL_AUTO_NORMAL);
746 glDisable (GL_NORMALIZE);
747 gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
748 gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
749 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
750 break;
751 }
752
753 gluBeginSurface (gl_nurb);
754 G4int u_stride = 4;
755 G4int v_stride = nurb.GetnbrCtrlPts(G4NURBS::U) * 4;
756
757 gluNurbsSurface (gl_nurb,
758 nurb.GetnbrKnots (G4NURBS::U), (GLfloat*)u_knot_array,
759 nurb.GetnbrKnots (G4NURBS::V), (GLfloat*)v_knot_array,
760 u_stride,
761 v_stride,
762 ctrl_pnt_array,
763 nurb.GetUorder (),
764 nurb.GetVorder (),
765 GL_MAP2_VERTEX_4);
766
767 gluEndSurface (gl_nurb);
768
769 delete [] u_knot_array; // These should be allocated with smart allocators
770 delete [] v_knot_array; // to avoid memory explosion.
771 delete [] ctrl_pnt_array;
772
773 gluDeleteNurbsRenderer (gl_nurb);
774}
775
776void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
777 G4VSceneHandler::AddCompound(traj); // For now.
778}
779
780void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
781 G4VSceneHandler::AddCompound(hit); // For now.
782}
783
784#endif
Note: See TracBrowser for help on using the repository browser.