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

Last change on this file since 1121 was 1116, checked in by garnier, 16 years ago

bug fix

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