G4OpenGLSceneHandler.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // Andrew Walkden  27th March 1996
00031 // OpenGL stored scene - creates OpenGL display lists.
00032 // OpenGL immediate scene - draws immediately to buffer
00033 //                           (saving space on server).
00034 
00035 #ifdef G4VIS_BUILD_OPENGL_DRIVER
00036 
00037 // Included here - problems with HP compiler if not before other includes?
00038 #include "G4NURBS.hh"
00039 
00040 // Here follows a special for Mesa, the OpenGL emulator.  Does not affect
00041 // other OpenGL's, as far as I'm aware.   John Allison 18/9/96.
00042 #define CENTERLINE_CLPP  /* CenterLine C++ workaround: */
00043 // Also seems to be required for HP's CC and AIX xlC, at least.
00044 
00045 #include "G4OpenGLSceneHandler.hh"
00046 #include "G4OpenGLViewer.hh"
00047 #include "G4OpenGLTransform3D.hh"
00048 #include "G4Point3D.hh"
00049 #include "G4Normal3D.hh"
00050 #include "G4Transform3D.hh"
00051 #include "G4Polyline.hh"
00052 #include "G4Polymarker.hh"
00053 #include "G4Text.hh"
00054 #include "G4Circle.hh"
00055 #include "G4Square.hh"
00056 #include "G4VMarker.hh"
00057 #include "G4Polyhedron.hh"
00058 #include "G4VisAttributes.hh"
00059 #include "G4PhysicalVolumeModel.hh"
00060 #include "G4VPhysicalVolume.hh"
00061 #include "G4LogicalVolume.hh"
00062 #include "G4VSolid.hh"
00063 #include "G4Scene.hh"
00064 #include "G4VisExtent.hh"
00065 #include "G4AttHolder.hh"
00066 #include "G4PhysicalConstants.hh"
00067 
00068 G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system,
00069                                             G4int id,
00070                                             const G4String& name):
00071 G4VSceneHandler (system, id, name),
00072 fPickName(0),
00073 // glFlush take about 90% time.  Dividing glFlush number by 100 will
00074 // change the first vis time from 100% to 10+90/100 = 10,9%.
00075 fEventsDrawInterval(1),
00076 fEventsWaitingToBeFlushed(0),
00077 fThreePassCapable(false),
00078 fSecondPassForTransparencyRequested(false),
00079 fSecondPassForTransparency(false),
00080 fThirdPassForNonHiddenMarkersRequested(false),
00081 fThirdPassForNonHiddenMarkers(false)
00082 {}
00083 
00084 G4OpenGLSceneHandler::~G4OpenGLSceneHandler ()
00085 {
00086   ClearStore ();
00087 }
00088 
00089 const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = {
00090   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00091   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00092   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00093   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00094   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00095   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00096   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00097   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00098   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00099   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00100   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00101   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00102   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00103   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00104   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
00105   0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
00106 };
00107 
00108 void G4OpenGLSceneHandler::ClearAndDestroyAtts()
00109 {
00110   std::map<GLuint, G4AttHolder*>::iterator i;
00111   for (i = fPickMap.begin(); i != fPickMap.end(); ++i) delete i->second;
00112   fPickMap.clear();
00113 }
00114 
00115 void G4OpenGLSceneHandler::ScaledFlush()
00116 {
00117   fEventsWaitingToBeFlushed++;
00118   if (fEventsWaitingToBeFlushed < fEventsDrawInterval) return;
00119   glFlush();
00120   fEventsWaitingToBeFlushed = 0;
00121 }
00122 
00123 void G4OpenGLSceneHandler::ProcessScene()
00124 {
00125   fThreePassCapable = true;
00126   
00127   G4VSceneHandler::ProcessScene();
00128 
00129   // Repeat if required...
00130   if (fSecondPassForTransparencyRequested) {
00131     fSecondPassForTransparency = true;
00132     G4VSceneHandler::ProcessScene();
00133     fSecondPassForTransparency = false;
00134     fSecondPassForTransparencyRequested = false;
00135   }
00136 
00137   // And again if required...
00138   if (fThirdPassForNonHiddenMarkersRequested) {
00139     fThirdPassForNonHiddenMarkers = true;
00140     G4VSceneHandler::ProcessScene();
00141     fThirdPassForNonHiddenMarkers = false;
00142     fThirdPassForNonHiddenMarkersRequested = false;
00143   }
00144   
00145   fThreePassCapable = false;
00146 }
00147 
00148 void G4OpenGLSceneHandler::PreAddSolid
00149 (const G4Transform3D& objectTransformation,
00150  const G4VisAttributes& visAttribs)
00151 {
00152   G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
00153 }
00154 
00155 void G4OpenGLSceneHandler::BeginPrimitives
00156 (const G4Transform3D& objectTransformation)
00157 {
00158   G4VSceneHandler::BeginPrimitives (objectTransformation);
00159 }
00160 
00161 void G4OpenGLSceneHandler::EndPrimitives ()
00162 {
00163   G4VSceneHandler::EndPrimitives ();
00164 }
00165 
00166 void G4OpenGLSceneHandler::BeginPrimitives2D
00167 (const G4Transform3D& objectTransformation)
00168 {
00169   G4VSceneHandler::BeginPrimitives2D (objectTransformation);
00170 }
00171 
00172 void G4OpenGLSceneHandler::EndPrimitives2D ()
00173 {
00174   G4VSceneHandler::EndPrimitives2D ();
00175 }
00176 
00177 G4VSolid* G4OpenGLSceneHandler::CreateSectionSolid ()
00178 {
00179   // Clipping done in G4OpenGLViewer::SetView.
00180   // return 0;
00181 
00182   // But...OpenGL no longer seems to reconstruct clipped edges, so,
00183   // when the BooleanProcessor is up to it, abandon this and use
00184   // generic clipping in G4VSceneHandler::CreateSectionSolid...
00185   return G4VSceneHandler::CreateSectionSolid();
00186 }
00187 
00188 G4VSolid* G4OpenGLSceneHandler::CreateCutawaySolid ()
00189 {
00190   // Cutaway done in G4OpenGLViewer::SetView.
00191   // return 0;
00192 
00193   // But...if not, when the BooleanProcessor is up to it...
00194   return G4VSceneHandler::CreateCutawaySolid();
00195 }
00196 
00197 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
00198 {
00199   G4int nPoints = line.size ();
00200   if (nPoints <= 0) return;
00201 
00202   // Note: colour and depth test treated in sub-class.
00203 
00204   glDisable (GL_LIGHTING);
00205 
00206   // Get vis attributes - pick up defaults if none.
00207   const G4VisAttributes* pVA =
00208     fpViewer -> GetApplicableVisAttributes (line.GetVisAttributes ());
00209 
00210   G4double lineWidth = GetLineWidth(pVA);
00211   // Need access to method in G4OpenGLViewer.  static_cast doesn't
00212   // work with a virtual base class, so use dynamic_cast.  No need to
00213   // test the outcome since viewer is guaranteed to be a
00214   // G4OpenGLViewer, but test it anyway to keep Coverity happy.
00215   G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
00216   if (pGLViewer) pGLViewer->ChangeLineWidth(lineWidth);
00217 
00218   glBegin (GL_LINE_STRIP);
00219   for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
00220   G4double x, y, z;
00221     x = line[iPoint].x(); 
00222     y = line[iPoint].y();
00223     z = line[iPoint].z();
00224     glVertex3d (x, y, z);
00225   }
00226   glEnd ();
00227 }
00228 
00229 void G4OpenGLSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
00230 {
00231   if (polymarker.size() == 0) {
00232     return;
00233   }
00234 
00235   // Note: colour and depth test treated in sub-class.
00236 
00237   glDisable (GL_LIGHTING);
00238   
00239   // Get vis attributes - pick up defaults if none.
00240   const G4VisAttributes* pVA =
00241     fpViewer -> GetApplicableVisAttributes (polymarker.GetVisAttributes ());
00242 
00243   G4double lineWidth = GetLineWidth(pVA);
00244   // Need access to method in G4OpenGLViewer.  static_cast doesn't
00245   // work with a virtual base class, so use dynamic_cast.  No need to
00246   // test the outcome since viewer is guaranteed to be a
00247   // G4OpenGLViewer, but test it anyway to keep Coverity happy.
00248   G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
00249   if (pGLViewer) pGLViewer->ChangeLineWidth(lineWidth);
00250 
00251   G4VMarker::FillStyle style = polymarker.GetFillStyle();
00252 
00253   // G4bool filled = false;  Not actually used - comment out to prevent compiler warnings (JA).
00254   static G4bool hashedWarned = false;
00255   
00256   switch (style) {
00257   case G4VMarker::noFill: 
00258     glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00259     //filled = false;
00260     break;
00261   case G4VMarker::hashed:
00262     if (!hashedWarned) {
00263       G4cout << "Hashed fill style in G4OpenGLSceneHandler."
00264              << "\n  Not implemented.  Using G4VMarker::filled."
00265              << G4endl;
00266       hashedWarned = true;
00267     }
00268     // Maybe use
00269     //glPolygonStipple (fStippleMaskHashed);
00270     // Drop through to filled...  
00271   case G4VMarker::filled:
00272     glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00273     //filled = true;
00274     break;
00275   }
00276 
00277   MarkerSizeType sizeType;
00278   G4double size = GetMarkerSize(polymarker, sizeType);
00279 
00280   // Draw...
00281   if (sizeType == world) {  // Size specified in world coordinates.
00282 
00283     G4int nSides;
00284     G4double startPhi;
00285     switch (polymarker.GetMarkerType()) {
00286     default:
00287     case G4Polymarker::dots:
00288       size = 1.;
00289       // Drop through to circles
00290     case G4Polymarker::circles:
00291       nSides = GetNoOfSides(pVA);
00292       startPhi = 0.;
00293       break;
00294     case G4Polymarker::squares:
00295       nSides = 4;
00296       startPhi = -pi / 4.;
00297       break;
00298     }
00299 
00300     const G4Vector3D& viewpointDirection =
00301       fpViewer -> GetViewParameters().GetViewpointDirection();
00302     const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
00303     const G4double dPhi = twopi / nSides;
00304     const G4double radius = size / 2.;
00305     G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
00306     G4double phi;
00307     G4int i;
00308     for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
00309       glBegin (GL_POLYGON);
00310       for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) {
00311         G4Vector3D r = start; r.rotate(phi, viewpointDirection);
00312         G4Vector3D p = polymarker[iPoint] + r;
00313         glVertex3d (p.x(), p.y(), p.z());
00314       }
00315       glEnd ();
00316     }
00317 
00318   } else { // Size specified in screen (window) coordinates.
00319 
00320     pGLViewer->ChangePointSize(size);
00321 
00322     //Antialiasing only for circles
00323     switch (polymarker.GetMarkerType()) {
00324     default:
00325     case G4Polymarker::dots:
00326     case G4Polymarker::circles:
00327       glEnable (GL_POINT_SMOOTH); break;
00328     case G4Polymarker::squares:
00329       glDisable (GL_POINT_SMOOTH); break;
00330     }
00331       
00332     glBegin (GL_POINTS);
00333     for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
00334       G4Point3D centre = polymarker[iPoint];
00335       glVertex3d(centre.x(),centre.y(),centre.z());
00336     }
00337     glEnd();     
00338   }
00339 }
00340 
00341 void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
00342   // Pass to specific viewer via virtual function DrawText.
00343   G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
00344   if (pGLViewer) pGLViewer->DrawText(text);
00345 }
00346 
00347 void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
00348   G4Polymarker oneCircle(circle);
00349   oneCircle.push_back(circle.GetPosition());
00350   oneCircle.SetMarkerType(G4Polymarker::circles);
00351   // Call this AddPrimitive to avoid re-doing sub-class code.
00352   G4OpenGLSceneHandler::AddPrimitive(oneCircle);
00353 }
00354 
00355 void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
00356   G4Polymarker oneSquare(square);
00357   oneSquare.push_back(square.GetPosition());
00358   oneSquare.SetMarkerType(G4Polymarker::squares);
00359   // Call this AddPrimitive to avoid re-doing sub-class code.
00360   G4OpenGLSceneHandler::AddPrimitive(oneSquare);
00361 }
00362 
00363 void G4OpenGLSceneHandler::AddPrimitive (const G4Scale& scale)
00364 {
00365   G4VSceneHandler::AddPrimitive(scale);
00366 }
00367 
00368 //Method for handling G4Polyhedron objects for drawing solids.
00369 void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
00370 
00371   // Assume all facets are planar convex quadrilaterals.
00372   // Draw each facet individually
00373   
00374   if (polyhedron.GetNoFacets() == 0) return;
00375 
00376   // Need access to data in G4OpenGLViewer.  static_cast doesn't work
00377   // with a virtual base class, so use dynamic_cast.
00378   G4OpenGLViewer* pGLViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
00379   if (!pGLViewer) return;
00380   
00381   // Get vis attributes - pick up defaults if none.
00382   const G4VisAttributes* pVA =
00383     fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
00384 
00385   // Get view parameters that the user can force through the vis
00386   // attributes, thereby over-riding the current view parameter.
00387   G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
00388 
00389   // Note that in stored mode, because this call gets embedded in a display
00390   //  list, it is the colour _at the time of_ creation of the display list, so
00391   //  even if the colour is changed, for example, by interaction with a Qt
00392   //  window, current_colour does not change.
00393   GLfloat current_colour [4];
00394   glGetFloatv (GL_CURRENT_COLOR, current_colour);
00395   
00396   G4bool isTransparent = false;
00397   if (current_colour[3] < 1.) {  // This object is transparent
00398     isTransparent = true;
00399   }
00400 
00401   // This is the colour used to paint surfaces in hlr mode.
00402   GLfloat clear_colour[4];
00403   glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
00404   
00405   G4double lineWidth = GetLineWidth(pVA);
00406   pGLViewer->ChangeLineWidth(lineWidth);
00407 
00408   G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
00409 
00410   G4bool clipping = pGLViewer->fVP.IsSection() || pGLViewer->fVP.IsCutaway();
00411 
00412   // Lighting disabled unless otherwise requested
00413   glDisable (GL_LIGHTING);
00414 
00415   switch (drawing_style) {
00416   case (G4ViewParameters::hlhsr):
00417     // Set up as for hidden line removal but paint polygon faces later...
00418   case (G4ViewParameters::hlr):
00419     glEnable (GL_STENCIL_TEST);
00420     // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
00421     // The procedure below leaves it clear.
00422     glStencilFunc (GL_ALWAYS, 0, 1);
00423     glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
00424     glEnable (GL_DEPTH_TEST);
00425     glDepthFunc (GL_LEQUAL);
00426     if (isTransparent) {
00427       // Transparent...
00428       glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00429       glEnable(GL_COLOR_MATERIAL);
00430       glDisable (GL_CULL_FACE);
00431       glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00432     } else {
00433       // Opaque...
00434       if (clipping) {
00435         glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00436         glEnable(GL_COLOR_MATERIAL);
00437         glDisable (GL_CULL_FACE);
00438         glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00439       } else {
00440         glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
00441         glEnable(GL_COLOR_MATERIAL);
00442         glEnable (GL_CULL_FACE);
00443         glCullFace (GL_BACK);
00444         glPolygonMode (GL_FRONT, GL_LINE);
00445       }
00446     }
00447     break;
00448   case (G4ViewParameters::hsr):
00449     glEnable (GL_DEPTH_TEST);
00450     glDepthFunc (GL_LEQUAL);    
00451     if (isTransparent) {
00452       // Transparent...
00453       glDepthMask (GL_FALSE);  // Make depth buffer read-only.
00454       glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00455       glEnable(GL_COLOR_MATERIAL);
00456       glDisable (GL_CULL_FACE);
00457       glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00458     } else {
00459       // Opaque...
00460       glDepthMask (GL_TRUE);  // Make depth buffer writable (default).
00461       if (clipping) {
00462         glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00463         glEnable(GL_COLOR_MATERIAL);
00464         glDisable (GL_CULL_FACE);
00465         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00466       } else {
00467         glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
00468         glEnable(GL_COLOR_MATERIAL);
00469         glEnable (GL_CULL_FACE);
00470         glCullFace (GL_BACK);
00471         glPolygonMode (GL_FRONT, GL_FILL);
00472       }
00473     }
00474     if (!fProcessing2D) glEnable (GL_LIGHTING);
00475     break;
00476   case (G4ViewParameters::wireframe):
00477   default:
00478     glEnable (GL_DEPTH_TEST);
00479     glDepthFunc (GL_LEQUAL);    //??? was GL_ALWAYS
00480     glDisable (GL_CULL_FACE);
00481     glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00482     break;
00483   }
00484 
00485   //Loop through all the facets...
00486   glBegin (GL_QUADS);
00487   G4bool notLastFace;
00488   do {
00489 
00490     //First, find vertices, edgeflags and normals and note "not last facet"...
00491     G4Point3D vertex[4];
00492     G4int edgeFlag[4];
00493     G4Normal3D normals[4];
00494     G4int nEdges;
00495     notLastFace = polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normals);
00496 
00497     //Loop through the four edges of each G4Facet...
00498     for(G4int edgeCount = 0; edgeCount < nEdges; ++edgeCount) {
00499       // Check to see if edge is visible or not...
00500       if (isAuxEdgeVisible) {
00501         edgeFlag[edgeCount] = 1;
00502       }
00503       if (edgeFlag[edgeCount] > 0) {
00504         glEdgeFlag (GL_TRUE);
00505       } else {
00506         glEdgeFlag (GL_FALSE);
00507       }
00508       glNormal3d (normals[edgeCount].x(), 
00509                   normals[edgeCount].y(),
00510                   normals[edgeCount].z());
00511       glVertex3d (vertex[edgeCount].x(), 
00512                   vertex[edgeCount].y(),
00513                   vertex[edgeCount].z());
00514     }
00515     // HepPolyhedron produces triangles too; in that case add an extra
00516     // vertex identical to first...
00517     if (nEdges == 3) {
00518       G4int edgeCount = 3;
00519       normals[edgeCount] = normals[0];
00520       vertex[edgeCount] = vertex[0];
00521       edgeFlag[edgeCount] = -1;
00522       glEdgeFlag (GL_FALSE);
00523       glNormal3d (normals[edgeCount].x(),
00524                   normals[edgeCount].y(), 
00525                   normals[edgeCount].z());
00526       glVertex3d (vertex[edgeCount].x(),
00527                   vertex[edgeCount].y(), 
00528                   vertex[edgeCount].z());
00529     }
00530     // Trap situation where number of edges is > 4...
00531     if (nEdges > 4) {
00532       G4cerr <<
00533         "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING"
00534         "\n   G4Polyhedron facet with " << nEdges << " edges" << G4endl;
00535     }
00536 
00537     glDisable(GL_COLOR_MATERIAL); // Revert to glMaterial for hlr/sr.
00538 
00539     // Do it all over again (twice) for hlr...
00540     if  (drawing_style == G4ViewParameters::hlr ||
00541          drawing_style == G4ViewParameters::hlhsr) {
00542 
00543       glEnd ();  // Placed here to balance glBegin above, allowing GL
00544                  // state changes below, then glBegin again.  Avoids
00545                  // having glBegin/End pairs *inside* loop in the more
00546                  // usual case of no hidden line removal.
00547 
00548       // Lighting disabled unless otherwise requested
00549       glDisable (GL_LIGHTING);
00550 
00551       // Draw through stencil...
00552       glStencilFunc (GL_EQUAL, 0, 1);
00553       glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
00554       if (drawing_style == G4ViewParameters::hlhsr) {
00555         if (!fProcessing2D) glEnable (GL_LIGHTING);
00556       }
00557       glEnable (GL_DEPTH_TEST);
00558       glDepthFunc (GL_LEQUAL);    
00559       if (isTransparent) {
00560         // Transparent...
00561         glDepthMask (GL_FALSE);  // Make depth buffer read-only.
00562         glDisable (GL_CULL_FACE);
00563         glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00564       } else {
00565         // Opaque...
00566         glDepthMask (GL_TRUE);  // Make depth buffer writable (default).
00567         if (clipping) {
00568           glDisable (GL_CULL_FACE);
00569           glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00570         } else {
00571           glEnable (GL_CULL_FACE);
00572           glCullFace (GL_BACK);
00573           glPolygonMode (GL_FRONT, GL_FILL);
00574         }
00575       }
00576       GLfloat* painting_colour;
00577       if  (drawing_style == G4ViewParameters::hlr) {
00578         if (isTransparent) {
00579           // Transparent - don't paint...
00580           goto end_of_drawing_through_stencil;
00581         }
00582         painting_colour = clear_colour;
00583       } else {  // drawing_style == G4ViewParameters::hlhsr
00584         painting_colour = current_colour;
00585       }
00586       if (isTransparent) {
00587         // Transparent...
00588         glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
00589       } else {
00590         // Opaque...
00591         glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
00592       }
00593       glColor4fv (painting_colour);
00594       glBegin (GL_QUADS);
00595       for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
00596         if (edgeFlag[edgeCount] > 0) {
00597           glEdgeFlag (GL_TRUE);
00598         } else {
00599           glEdgeFlag (GL_FALSE);
00600         }
00601         glNormal3d (normals[edgeCount].x(), 
00602                     normals[edgeCount].y(),
00603                     normals[edgeCount].z());
00604         glVertex3d (vertex[edgeCount].x(), 
00605                     vertex[edgeCount].y(),
00606                     vertex[edgeCount].z());
00607       }
00608       glEnd ();
00609     end_of_drawing_through_stencil:
00610 
00611       // and once more to reset the stencil bits...
00612       glStencilFunc (GL_ALWAYS, 0, 1);
00613       glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
00614       glDepthFunc (GL_LEQUAL);  // to make sure line gets drawn.  
00615       if (isTransparent) {
00616         // Transparent...
00617         glDisable (GL_CULL_FACE);
00618         glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00619       } else {
00620         // Opaque...
00621         if (clipping) {
00622           glDisable (GL_CULL_FACE);
00623           glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00624         } else {
00625           glEnable (GL_CULL_FACE);
00626           glCullFace (GL_BACK);
00627           glPolygonMode (GL_FRONT, GL_LINE);
00628         }
00629       }
00630       glDisable (GL_LIGHTING);
00631       glColor4fv (current_colour);
00632       glBegin (GL_QUADS);
00633       for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
00634         if (edgeFlag[edgeCount] > 0) {
00635           glEdgeFlag (GL_TRUE);
00636         } else {
00637           glEdgeFlag (GL_FALSE);
00638         }
00639         glNormal3d (normals[edgeCount].x(), 
00640                     normals[edgeCount].y(),
00641                     normals[edgeCount].z());
00642         glVertex3d (vertex[edgeCount].x(), 
00643                     vertex[edgeCount].y(),
00644                     vertex[edgeCount].z());
00645       }
00646       glEnd ();
00647       glDepthFunc (GL_LEQUAL);   // Revert for next facet.
00648       glBegin (GL_QUADS);      // Ready for next facet.  GL
00649                                // says it ignores incomplete
00650                                // quadrilaterals, so final empty
00651                                // glBegin/End sequence should be OK.
00652     }
00653   } while (notLastFace);  
00654   
00655   glEnd ();
00656   glDisable (GL_STENCIL_TEST);  // Revert to default for next primitive.
00657   glDepthMask (GL_TRUE);        // Revert to default for next primitive.
00658   glDisable (GL_LIGHTING);      // Revert to default for next primitive.
00659 }
00660 
00661 //Method for handling G4NURBS objects for drawing solids.
00662 //Knots and Ctrl Pnts MUST be arrays of GLfloats.
00663 void G4OpenGLSceneHandler::AddPrimitive (const G4NURBS& nurb) {
00664 
00665   GLUnurbsObj *gl_nurb;
00666   gl_nurb = gluNewNurbsRenderer ();
00667 
00668   GLfloat *u_knot_array, *u_knot_array_ptr;
00669   u_knot_array = u_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::U)];
00670   G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
00671   while (u_iterator.pick (u_knot_array_ptr++)){}
00672 
00673   GLfloat *v_knot_array, *v_knot_array_ptr;
00674   v_knot_array = v_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::V)];
00675   G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
00676   while (v_iterator.pick (v_knot_array_ptr++)){}
00677 
00678   GLfloat *ctrl_pnt_array, *ctrl_pnt_array_ptr;
00679   ctrl_pnt_array = ctrl_pnt_array_ptr =
00680     new GLfloat [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC];
00681   G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
00682   while (c_p_iterator.pick (ctrl_pnt_array_ptr++)){}
00683 
00684   // Get vis attributes - pick up defaults if none.
00685   const G4VisAttributes* pVA =
00686     fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
00687 
00688   // Get view parameters that the user can force through the vis
00689   // attributes, thereby over-riding the current view parameter.
00690   G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
00691   //G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
00692   
00693   //Get colour, etc..
00694   const G4Colour& c = pVA -> GetColour ();
00695 
00696   switch (drawing_style) {
00697 
00698   case (G4ViewParameters::hlhsr):
00699     //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
00700     // << "Using hidden surface removal." << G4endl;
00701   case (G4ViewParameters::hsr):
00702     {
00703       if (!fProcessing2D) glEnable (GL_LIGHTING);
00704       glEnable (GL_DEPTH_TEST);
00705       glEnable (GL_AUTO_NORMAL);
00706       glEnable (GL_NORMALIZE);
00707       gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_FILL);
00708       gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
00709       GLfloat materialColour [4];
00710       materialColour [0] = c.GetRed ();
00711       materialColour [1] = c.GetGreen ();
00712       materialColour [2] = c.GetBlue ();
00713       materialColour [3] = 1.0;  // = c.GetAlpha () for transparency -
00714                                  // but see complication in
00715                                  // AddPrimitive(const G4Polyhedron&).
00716       glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
00717       break;
00718     }
00719   case (G4ViewParameters::hlr):
00720     //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
00721     // << "Using wireframe." << G4endl;
00722   case (G4ViewParameters::wireframe):
00723   default:
00724     glDisable (GL_LIGHTING);
00725 //    glDisable (GL_DEPTH_TEST);
00726     glEnable (GL_DEPTH_TEST);
00727     glDisable (GL_AUTO_NORMAL);
00728     glDisable (GL_NORMALIZE);
00729     gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
00730     gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
00731     glColor4d(c.GetRed(), c.GetGreen(), c.GetBlue(),c.GetAlpha());
00732     break;
00733   }     
00734 
00735   gluBeginSurface (gl_nurb);
00736   G4int u_stride = 4;
00737   G4int v_stride = nurb.GetnbrCtrlPts(G4NURBS::U) * 4;
00738 
00739   gluNurbsSurface (gl_nurb, 
00740                    nurb.GetnbrKnots (G4NURBS::U), (GLfloat*)u_knot_array, 
00741                    nurb.GetnbrKnots (G4NURBS::V), (GLfloat*)v_knot_array,
00742                    u_stride,
00743                    v_stride,  
00744                    ctrl_pnt_array,
00745                    nurb.GetUorder (),
00746                    nurb.GetVorder (), 
00747                    GL_MAP2_VERTEX_4);
00748   
00749   gluEndSurface (gl_nurb);
00750 
00751   delete [] u_knot_array;  // These should be allocated with smart allocators
00752   delete [] v_knot_array;  // to avoid memory explosion.
00753   delete [] ctrl_pnt_array;
00754 
00755   gluDeleteNurbsRenderer (gl_nurb);
00756 }
00757 
00758 void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
00759   G4VSceneHandler::AddCompound(traj);  // For now.
00760 }
00761 
00762 void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
00763   G4VSceneHandler::AddCompound(hit);  // For now.
00764 }
00765 
00766 void G4OpenGLSceneHandler::AddCompound(const G4VDigi& digi) {
00767   G4VSceneHandler::AddCompound(digi);  // For now.
00768 }
00769 
00770 void G4OpenGLSceneHandler::AddCompound(const G4THitsMap<G4double>& hits) {
00771   G4VSceneHandler::AddCompound(hits);  // For now.
00772 }
00773 
00774 #endif

Generated on Mon May 27 17:49:10 2013 for Geant4 by  doxygen 1.4.7