source: trunk/source/visualization/OpenGL/src/G4OpenGLSceneHandler.cc@ 1098

Last change on this file since 1098 was 1049, checked in by garnier, 17 years ago

update pas dans CVS

  • Property svn:mime-type set to text/cpp
File size: 26.6 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.55 2009/03/03 14:51:29 lgarnier Exp $
28// GEANT4 tag $Name: $
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 "G4Polymarker.hh"
55#include "G4Text.hh"
56#include "G4Circle.hh"
57#include "G4Square.hh"
58#include "G4VMarker.hh"
59#include "G4Polyhedron.hh"
60#include "G4VisAttributes.hh"
61#include "G4PhysicalVolumeModel.hh"
62#include "G4VPhysicalVolume.hh"
63#include "G4LogicalVolume.hh"
64#include "G4VSolid.hh"
65#include "G4Scene.hh"
66#include "G4VisExtent.hh"
67#include "G4AttHolder.hh"
68
69G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system,
70 G4int id,
71 const G4String& name):
72 G4VSceneHandler (system, id, name),
73 fPickName(0),
74 fProcessing2D (false),
75 fProcessingPolymarker(false)
76{
77#ifdef G4DEBUG_VIS_OGL
78 printf("INIT G4OpenGLSceneHandler (after G4OpenGLSceneHandler G4VSceneHandler (system, id, name)\n");
79#endif
80}
81
82G4OpenGLSceneHandler::~G4OpenGLSceneHandler ()
83{
84 ClearStore ();
85}
86
87const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = {
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 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
96 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
97 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
98 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
99 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
100 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
101 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
102 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
103 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
104};
105
106void G4OpenGLSceneHandler::ClearAndDestroyAtts()
107{
108 std::map<GLuint, G4AttHolder*>::iterator i;
109 for (i = fPickMap.begin(); i != fPickMap.end(); ++i) delete i->second;
110 fPickMap.clear();
111}
112
113void G4OpenGLSceneHandler::PreAddSolid
114(const G4Transform3D& objectTransformation,
115 const G4VisAttributes& visAttribs)
116{
117 G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
118}
119
120void G4OpenGLSceneHandler::BeginPrimitives
121(const G4Transform3D& objectTransformation)
122{
123 G4VSceneHandler::BeginPrimitives (objectTransformation);
124}
125
126void G4OpenGLSceneHandler::EndPrimitives ()
127{
128 G4VSceneHandler::EndPrimitives ();
129}
130
131void G4OpenGLSceneHandler::BeginPrimitives2D
132(const G4Transform3D& objectTransformation)
133{
134 G4VSceneHandler::BeginPrimitives2D (objectTransformation);
135 fProcessing2D = true;
136}
137
138void G4OpenGLSceneHandler::EndPrimitives2D ()
139{
140 fProcessing2D = false;
141 G4VSceneHandler::EndPrimitives2D ();
142}
143
144const G4Polyhedron* G4OpenGLSceneHandler::CreateSectionPolyhedron ()
145{
146 // Clipping done in G4OpenGLViewer::SetView.
147 return 0;
148
149 // But...OpenGL no longer seems to reconstruct clipped edges, so,
150 // when the BooleanProcessor is up to it, abandon this and use
151 // generic clipping in G4VSceneHandler::CreateSectionPolyhedron...
152 // return G4VSceneHandler::CreateSectionPolyhedron();
153}
154
155const G4Polyhedron* G4OpenGLSceneHandler::CreateCutawayPolyhedron ()
156{
157 // Cutaway done in G4OpenGLViewer::SetView.
158 return 0;
159
160 // But...if not, when the BooleanProcessor is up to it...
161 // return G4VSceneHandler::CreateCutawayPolyhedron();
162}
163
164void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
165{
166 G4int nPoints = line.size ();
167 if (nPoints <= 0) return;
168
169 // Loads G4Atts for picking...
170 if (fpViewer->GetViewParameters().IsPicking()) {
171 G4AttHolder* holder = new G4AttHolder;
172 LoadAtts(line, holder);
173 fPickMap[fPickName] = holder;
174 }
175
176 // Note: colour treated in sub-class.
177
178 if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
179 glDisable (GL_DEPTH_TEST);
180 else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
181
182 glDisable (GL_LIGHTING);
183
184 // Get vis attributes - pick up defaults if none.
185 const G4VisAttributes* pVA =
186 fpViewer -> GetApplicableVisAttributes (line.GetVisAttributes ());
187
188 G4double lineWidth = GetLineWidth(pVA);
189 glLineWidth(lineWidth);
190
191 glBegin (GL_LINE_STRIP);
192 for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
193 G4double x, y, z;
194 x = line[iPoint].x();
195 y = line[iPoint].y();
196 z = line[iPoint].z();
197 glVertex3d (x, y, z);
198 }
199 glEnd ();
200}
201
202void G4OpenGLSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
203{
204 G4int nPoints = polymarker.size ();
205 if (nPoints <= 0) return;
206
207 fProcessingPolymarker = true;
208
209 // Loads G4Atts for picking...
210 if (fpViewer->GetViewParameters().IsPicking()) {
211 G4AttHolder* holder = new G4AttHolder;
212 LoadAtts(polymarker, holder);
213 fPickMap[fPickName] = holder;
214 }
215
216 switch (polymarker.GetMarkerType()) {
217 default:
218 case G4Polymarker::dots:
219 {
220 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
221 G4Circle dot (polymarker);
222 dot.SetPosition (polymarker[iPoint]);
223 dot.SetWorldSize (0.);
224 dot.SetScreenSize (0.1); // Very small circle.
225 G4OpenGLSceneHandler::AddPrimitive (dot);
226 }
227 }
228 break;
229 case G4Polymarker::circles:
230 {
231 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
232 G4Circle circle (polymarker);
233 circle.SetPosition (polymarker[iPoint]);
234 G4OpenGLSceneHandler::AddPrimitive (circle);
235 }
236 }
237 break;
238 case G4Polymarker::squares:
239 {
240 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
241 G4Square square (polymarker);
242 square.SetPosition (polymarker[iPoint]);
243 G4OpenGLSceneHandler::AddPrimitive (square);
244 }
245 }
246 break;
247 }
248
249 fProcessingPolymarker = false;
250}
251
252void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
253
254 // Loads G4Atts for picking...
255 if (fpViewer->GetViewParameters().IsPicking()) {
256 G4AttHolder* holder = new G4AttHolder;
257 LoadAtts(text, holder);
258 fPickMap[fPickName] = holder;
259 }
260
261 const G4Colour& c = GetTextColour (text); // Picks up default if none.
262 MarkerSizeType sizeType;
263 G4double size = GetMarkerSize (text, sizeType);
264 G4ThreeVector position (text.GetPosition ());
265 G4String textString = text.GetText();
266
267 G4int font_base = G4OpenGLFontBaseStore::GetFontBase(fpViewer,size);
268 if (font_base < 0) {
269 static G4int callCount = 0;
270 ++callCount;
271 if (callCount <= 10 || callCount%100 == 0) {
272 G4cout <<
273 "G4OpenGLSceneHandler::AddPrimitive (const G4Text&) call count "
274 << callCount <<
275 "\n No fonts available."
276 "\n Called with text \""
277 << text.GetText ()
278 << "\"\n at " << position
279 << ", size " << size
280 << ", offsets " << text.GetXOffset () << ", " << text.GetYOffset ()
281 << ", type " << G4int(sizeType)
282 << ", colour " << c
283 << G4endl;
284 }
285 return;
286 }
287 const char* textCString = textString.c_str();
288 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
289 glDisable (GL_DEPTH_TEST);
290 glDisable (GL_LIGHTING);
291
292 glRasterPos3d(position.x(),position.y(),position.z());
293 // No action on offset or layout at present.
294 glPushAttrib(GL_LIST_BIT);
295 glListBase(font_base);
296 glCallLists(strlen(textCString), GL_UNSIGNED_BYTE, (GLubyte *)textCString);
297 glPopAttrib();
298}
299
300void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
301 glEnable (GL_POINT_SMOOTH);
302 AddCircleSquare (circle, G4OpenGLBitMapStore::circle);
303}
304
305void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
306 glDisable (GL_POINT_SMOOTH);
307 AddCircleSquare (square, G4OpenGLBitMapStore::square);
308}
309
310void G4OpenGLSceneHandler::AddCircleSquare
311(const G4VMarker& marker,
312 G4OpenGLBitMapStore::Shape shape) {
313
314 if (!fProcessingPolymarker) { // Polymarker has already loaded atts.
315 // Loads G4Atts for picking...
316 if (fpViewer->GetViewParameters().IsPicking()) {
317 G4AttHolder* holder = new G4AttHolder;
318 LoadAtts(marker, holder);
319 fPickMap[fPickName] = holder;
320 }
321 }
322
323 // Note: colour treated in sub-class.
324
325 if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
326 glDisable (GL_DEPTH_TEST);
327 else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
328
329 glDisable (GL_LIGHTING);
330
331 // Get vis attributes - pick up defaults if none.
332 const G4VisAttributes* pVA =
333 fpViewer -> GetApplicableVisAttributes (marker.GetVisAttributes ());
334
335 G4double lineWidth = GetLineWidth(pVA);
336 glLineWidth(lineWidth);
337
338 G4VMarker::FillStyle style = marker.GetFillStyle();
339
340 G4bool filled = false;
341 static G4bool hashedWarned = false;
342
343 switch (style) {
344 case G4VMarker::noFill:
345 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
346 filled = false;
347 break;
348
349 case G4VMarker::hashed:
350 if (!hashedWarned) {
351 G4cout << "Hashed fill style in G4OpenGLSceneHandler."
352 << "\n Not implemented. Using G4VMarker::filled."
353 << G4endl;
354 hashedWarned = true;
355 }
356 // Maybe use
357 //glPolygonStipple (fStippleMaskHashed);
358 // Drop through to filled...
359
360 case G4VMarker::filled:
361 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
362 filled = true;
363 break;
364
365 }
366
367 // A few useful quantities...
368 G4Point3D centre = marker.GetPosition();
369 MarkerSizeType sizeType;
370 G4double size = GetMarkerSize(marker, sizeType);
371
372 // Draw...
373 if (sizeType == world) { // Size specified in world coordinates.
374
375 DrawXYPolygon (shape, size, centre, pVA);
376
377 } else { // Size specified in screen (window) coordinates.
378 glPointSize (size);
379 glBegin (GL_POINTS);
380 glVertex3f(centre.x(),centre.y(),centre.z());
381 glEnd();
382 //Antialiasing
383 glEnable (GL_POINT_SMOOTH);
384 //Transparency
385 glEnable(GL_BLEND);
386 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
387
388 // L. GARNIER 1 March 2009
389 // Old method, we draw a bitmap instead of a GL_POINT.
390 // I remove it because it cost in term of computing performances
391 // and gl2ps can't draw bitmaps
392
393 // glRasterPos3d(centre.x(),centre.y(),centre.z());
394 // const GLubyte* marker =
395 // G4OpenGLBitMapStore::GetBitMap(shape, size, filled);
396 // glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
397 // glBitmap(GLsizei(size), GLsizei(size), size/2., size/2., 0., 0., marker);
398 }
399}
400
401void G4OpenGLSceneHandler::DrawXYPolygon
402(G4OpenGLBitMapStore::Shape shape,
403 G4double size,
404 const G4Point3D& centre,
405 const G4VisAttributes* pApplicableVisAtts)
406{
407 G4int nSides;
408 G4double startPhi;
409 if (shape == G4OpenGLBitMapStore::circle) {
410 nSides = GetNoOfSides(pApplicableVisAtts);
411 startPhi = 0.;
412 } else {
413 nSides = 4;
414 startPhi = -pi / 4.;
415 }
416
417 const G4Vector3D& viewpointDirection =
418 fpViewer -> GetViewParameters().GetViewpointDirection();
419 const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
420 const G4double dPhi = twopi / nSides;
421 const G4double radius = size / 2.;
422 G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
423 G4double phi;
424 G4int i;
425
426 glBegin (GL_POLYGON);
427 for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) {
428 G4Vector3D r = start; r.rotate(phi, viewpointDirection);
429 G4Vector3D p = centre + r;
430 glVertex3d (p.x(), p.y(), p.z());
431 }
432 glEnd ();
433}
434
435void G4OpenGLSceneHandler::AddPrimitive (const G4Scale& scale)
436{
437 G4VSceneHandler::AddPrimitive(scale);
438}
439
440//Method for handling G4Polyhedron objects for drawing solids.
441void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
442 // Assume all facets are planar convex quadrilaterals.
443 // Draw each facet individually
444
445 if (polyhedron.GetNoFacets() == 0) return;
446
447 // Loads G4Atts for picking...
448 if (fpViewer->GetViewParameters().IsPicking()) {
449 G4AttHolder* holder = new G4AttHolder;
450 const G4Visible vis;
451 printf ("G4OpenGLSceneHandler::AddPrimitives poly %d",&polyhedron);
452 LoadAtts(vis, holder);
453 // LoadAtts(polyhedron, holder);
454 fPickMap[fPickName] = holder;
455 }
456
457 // Get vis attributes - pick up defaults if none.
458 const G4VisAttributes* pVA =
459 fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
460
461 // Get view parameters that the user can force through the vis
462 // attributes, thereby over-riding the current view parameter.
463 G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
464
465 //Get colour, etc...
466 G4bool transparency_enabled = true;
467 G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
468 if (pViewer) transparency_enabled = pViewer->transparency_enabled;
469 const G4Colour& c = pVA->GetColour();
470 GLfloat materialColour [4];
471 materialColour [0] = c.GetRed ();
472 materialColour [1] = c.GetGreen ();
473 materialColour [2] = c.GetBlue ();
474 if (transparency_enabled) {
475 materialColour [3] = c.GetAlpha ();
476 } else {
477 materialColour [3] = 1.;
478 }
479
480 G4double lineWidth = GetLineWidth(pVA);
481 glLineWidth(lineWidth);
482
483 GLfloat clear_colour[4];
484 glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
485
486 G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
487
488 G4bool clipping = pViewer->fVP.IsSection() || pViewer->fVP.IsCutaway();
489
490 // Lighting disabled unless otherwise requested
491 glDisable (GL_LIGHTING);
492
493 switch (drawing_style) {
494 case (G4ViewParameters::hlhsr):
495 // Set up as for hidden line removal but paint polygon faces later...
496 case (G4ViewParameters::hlr):
497 glEnable (GL_STENCIL_TEST);
498 // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
499 // The procedure below leaves it clear.
500 glStencilFunc (GL_ALWAYS, 0, 1);
501 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
502 glEnable (GL_DEPTH_TEST);
503 glDepthFunc (GL_LEQUAL);
504 if (materialColour[3] < 1.) {
505 // Transparent...
506 glDisable (GL_CULL_FACE);
507 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
508 } else {
509 // Opaque...
510 if (clipping) {
511 glDisable (GL_CULL_FACE);
512 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
513 } else {
514 glEnable (GL_CULL_FACE);
515 glCullFace (GL_BACK);
516 glPolygonMode (GL_FRONT, GL_LINE);
517 }
518 }
519 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
520 break;
521 case (G4ViewParameters::hsr):
522 glEnable (GL_DEPTH_TEST);
523 glDepthFunc (GL_LEQUAL);
524 if (materialColour[3] < 1.) {
525 // Transparent...
526 glDepthMask (0); // Make depth buffer read-only.
527 glDisable (GL_CULL_FACE);
528 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
529 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, materialColour);
530 } else {
531 // Opaque...
532 glDepthMask (1); // Make depth buffer writable (default).
533 if (clipping) {
534 glDisable (GL_CULL_FACE);
535 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
536 } else {
537 glEnable (GL_CULL_FACE);
538 glCullFace (GL_BACK);
539 glPolygonMode (GL_FRONT, GL_FILL);
540 }
541 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
542 }
543 if (!fProcessing2D) glEnable (GL_LIGHTING);
544 break;
545 case (G4ViewParameters::wireframe):
546 default:
547 glEnable (GL_DEPTH_TEST);
548 glDepthFunc (GL_LEQUAL); //??? was GL_ALWAYS
549 glDisable (GL_CULL_FACE);
550 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
551 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
552 break;
553 }
554
555 //Loop through all the facets...
556 glBegin (GL_QUADS);
557 G4bool notLastFace;
558 do {
559
560 //First, find vertices, edgeflags and normals and note "not last facet"...
561 G4Point3D vertex[4];
562 G4int edgeFlag[4];
563 G4Normal3D normals[4];
564 G4int n;
565 notLastFace = polyhedron.GetNextFacet(n, vertex, edgeFlag, normals);
566
567 //Loop through the four edges of each G4Facet...
568 G4int edgeCount = 0;
569 for(edgeCount = 0; edgeCount < n; ++edgeCount) {
570 // Check to see if edge is visible or not...
571 if (isAuxEdgeVisible) {
572 edgeFlag[edgeCount] = 1;
573 }
574 if (edgeFlag[edgeCount] > 0) {
575 glEdgeFlag (GL_TRUE);
576 } else {
577 glEdgeFlag (GL_FALSE);
578 }
579 glNormal3d (normals[edgeCount].x(),
580 normals[edgeCount].y(),
581 normals[edgeCount].z());
582 glVertex3d (vertex[edgeCount].x(),
583 vertex[edgeCount].y(),
584 vertex[edgeCount].z());
585 }
586 // HepPolyhedron produces triangles too; in that case add an extra
587 // vertex identical to first...
588 if (n == 3) {
589 edgeCount = 3;
590 normals[edgeCount] = normals[0];
591 vertex[edgeCount] = vertex[0];
592 edgeFlag[edgeCount] = -1;
593 glEdgeFlag (GL_FALSE);
594 glNormal3d (normals[edgeCount].x(),
595 normals[edgeCount].y(),
596 normals[edgeCount].z());
597 glVertex3d (vertex[edgeCount].x(),
598 vertex[edgeCount].y(),
599 vertex[edgeCount].z());
600 }
601 // Trap situation where number of edges is > 4...
602 if (n > 4) {
603 G4cerr <<
604 "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING";
605 G4PhysicalVolumeModel* pPVModel =
606 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
607 if (pPVModel) {
608 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
609 G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
610 G4cerr <<
611 "\n Volume " << pCurrentPV->GetName() <<
612 ", Solid " << pCurrentLV->GetSolid()->GetName() <<
613 " (" << pCurrentLV->GetSolid()->GetEntityType();
614 }
615 G4cerr<<
616 "\n G4Polyhedron facet with " << n << " edges" << G4endl;
617 }
618
619 // Do it all over again (twice) for hlr...
620 if (drawing_style == G4ViewParameters::hlr ||
621 drawing_style == G4ViewParameters::hlhsr) {
622
623 glEnd (); // Placed here to balance glBegin above, allowing GL
624 // state changes below, then glBegin again. Avoids
625 // having glBegin/End pairs *inside* loop in the more
626 // usual case of no hidden line removal.
627
628 // Lighting disabled unless otherwise requested
629 glDisable (GL_LIGHTING);
630
631 // Draw through stencil...
632 glStencilFunc (GL_EQUAL, 0, 1);
633 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
634 if (drawing_style == G4ViewParameters::hlhsr) {
635 if (!fProcessing2D) glEnable (GL_LIGHTING);
636 }
637 glEnable (GL_DEPTH_TEST);
638 glDepthFunc (GL_LEQUAL);
639 if (materialColour[3] < 1.) {
640 // Transparent...
641 glDepthMask (0); // Make depth buffer read-only.
642 glDisable (GL_CULL_FACE);
643 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
644 } else {
645 // Opaque...
646 glDepthMask (1); // Make depth buffer writable (default).
647 if (clipping) {
648 glDisable (GL_CULL_FACE);
649 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
650 } else {
651 glEnable (GL_CULL_FACE);
652 glCullFace (GL_BACK);
653 glPolygonMode (GL_FRONT, GL_FILL);
654 }
655 }
656 GLfloat* painting_colour;
657 if (drawing_style == G4ViewParameters::hlr) {
658 if (materialColour[3] < 1.) {
659 // Transparent - don't paint...
660 goto end_of_drawing_through_stencil;
661 }
662 painting_colour = clear_colour;
663 } else { // drawing_style == G4ViewParameters::hlhsr
664 painting_colour = materialColour;
665 }
666 if (materialColour[3] < 1.) {
667 // Transparent...
668 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
669 } else {
670 // Opaque...
671 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
672 }
673 glColor4fv (painting_colour);
674 glBegin (GL_QUADS);
675 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
676 if (edgeFlag[edgeCount] > 0) {
677 glEdgeFlag (GL_TRUE);
678 } else {
679 glEdgeFlag (GL_FALSE);
680 }
681 glNormal3d (normals[edgeCount].x(),
682 normals[edgeCount].y(),
683 normals[edgeCount].z());
684 glVertex3d (vertex[edgeCount].x(),
685 vertex[edgeCount].y(),
686 vertex[edgeCount].z());
687 }
688 glEnd ();
689 end_of_drawing_through_stencil:
690
691 // and once more to reset the stencil bits...
692 glStencilFunc (GL_ALWAYS, 0, 1);
693 glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
694 glDepthFunc (GL_LEQUAL); // to make sure line gets drawn.
695 if (materialColour[3] < 1.) {
696 // Transparent...
697 glDisable (GL_CULL_FACE);
698 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
699 } else {
700 // Opaque...
701 if (clipping) {
702 glDisable (GL_CULL_FACE);
703 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
704 } else {
705 glEnable (GL_CULL_FACE);
706 glCullFace (GL_BACK);
707 glPolygonMode (GL_FRONT, GL_LINE);
708 }
709 }
710 glDisable (GL_LIGHTING);
711 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
712 glBegin (GL_QUADS);
713 for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
714 if (edgeFlag[edgeCount] > 0) {
715 glEdgeFlag (GL_TRUE);
716 } else {
717 glEdgeFlag (GL_FALSE);
718 }
719 glNormal3d (normals[edgeCount].x(),
720 normals[edgeCount].y(),
721 normals[edgeCount].z());
722 glVertex3d (vertex[edgeCount].x(),
723 vertex[edgeCount].y(),
724 vertex[edgeCount].z());
725 }
726 glEnd ();
727 glDepthFunc (GL_LEQUAL); // Revert for next facet.
728 glBegin (GL_QUADS); // Ready for next facet. GL
729 // says it ignores incomplete
730 // quadrilaterals, so final empty
731 // glBegin/End sequence should be OK.
732 }
733 } while (notLastFace);
734
735 glEnd ();
736 glDisable (GL_STENCIL_TEST); // Revert to default for next primitive.
737 glDepthMask (1); // Revert to default for next primitive.
738 glDisable (GL_LIGHTING); // Revert to default for next primitive.
739}
740
741//Method for handling G4NURBS objects for drawing solids.
742//Knots and Ctrl Pnts MUST be arrays of GLfloats.
743void G4OpenGLSceneHandler::AddPrimitive (const G4NURBS& nurb) {
744
745 // Loads G4Atts for picking...
746 if (fpViewer->GetViewParameters().IsPicking()) {
747 G4AttHolder* holder = new G4AttHolder;
748 LoadAtts(nurb, holder);
749 fPickMap[fPickName] = holder;
750 }
751
752 GLUnurbsObj *gl_nurb;
753 gl_nurb = gluNewNurbsRenderer ();
754
755 GLfloat *u_knot_array, *u_knot_array_ptr;
756 u_knot_array = u_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::U)];
757 G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
758 while (u_iterator.pick (u_knot_array_ptr++)){}
759
760 GLfloat *v_knot_array, *v_knot_array_ptr;
761 v_knot_array = v_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::V)];
762 G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
763 while (v_iterator.pick (v_knot_array_ptr++)){}
764
765 GLfloat *ctrl_pnt_array, *ctrl_pnt_array_ptr;
766 ctrl_pnt_array = ctrl_pnt_array_ptr =
767 new GLfloat [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC];
768 G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
769 while (c_p_iterator.pick (ctrl_pnt_array_ptr++)){}
770
771 // Get vis attributes - pick up defaults if none.
772 const G4VisAttributes* pVA =
773 fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
774
775 // Get view parameters that the user can force through the vis
776 // attributes, thereby over-riding the current view parameter.
777 G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
778 //G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
779
780 //Get colour, etc..
781 const G4Colour& c = pVA -> GetColour ();
782
783 switch (drawing_style) {
784
785 case (G4ViewParameters::hlhsr):
786 // G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
787 // << "Using hidden surface removal." << G4endl;
788 case (G4ViewParameters::hsr):
789 {
790 if (!fProcessing2D) glEnable (GL_LIGHTING);
791 glEnable (GL_DEPTH_TEST);
792 glEnable (GL_AUTO_NORMAL);
793 glEnable (GL_NORMALIZE);
794 gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_FILL);
795 gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
796 GLfloat materialColour [4];
797 materialColour [0] = c.GetRed ();
798 materialColour [1] = c.GetGreen ();
799 materialColour [2] = c.GetBlue ();
800 materialColour [3] = 1.0; // = c.GetAlpha () for transparency -
801 // but see complication in
802 // AddPrimitive(const G4Polyhedron&).
803 glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
804 break;
805 }
806 case (G4ViewParameters::hlr):
807 // G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
808 // << "Using wireframe." << G4endl;
809 case (G4ViewParameters::wireframe):
810 default:
811 glDisable (GL_LIGHTING);
812// glDisable (GL_DEPTH_TEST);
813 glEnable (GL_DEPTH_TEST);
814 glDisable (GL_AUTO_NORMAL);
815 glDisable (GL_NORMALIZE);
816 gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
817 gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
818 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
819 break;
820 }
821
822 gluBeginSurface (gl_nurb);
823 G4int u_stride = 4;
824 G4int v_stride = nurb.GetnbrCtrlPts(G4NURBS::U) * 4;
825
826 gluNurbsSurface (gl_nurb,
827 nurb.GetnbrKnots (G4NURBS::U), (GLfloat*)u_knot_array,
828 nurb.GetnbrKnots (G4NURBS::V), (GLfloat*)v_knot_array,
829 u_stride,
830 v_stride,
831 ctrl_pnt_array,
832 nurb.GetUorder (),
833 nurb.GetVorder (),
834 GL_MAP2_VERTEX_4);
835
836 gluEndSurface (gl_nurb);
837
838 delete [] u_knot_array; // These should be allocated with smart allocators
839 delete [] v_knot_array; // to avoid memory explosion.
840 delete [] ctrl_pnt_array;
841
842 gluDeleteNurbsRenderer (gl_nurb);
843}
844
845void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
846 G4VSceneHandler::AddCompound(traj); // For now.
847}
848
849void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
850 G4VSceneHandler::AddCompound(hit); // For now.
851}
852
853#endif
Note: See TracBrowser for help on using the repository browser.