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

Last change on this file since 1115 was 1113, checked in by garnier, 16 years ago

en debug.....

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