// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4OpenGLViewer.cc,v 1.29 2006/09/19 16:13:15 allison Exp $ // GEANT4 tag $Name: geant4-08-02-patch-01 $ // // // Andrew Walkden 27th March 1996 // OpenGL view - opens window, hard copy, etc. #ifdef G4VIS_BUILD_OPENGL_DRIVER #include "G4ios.hh" #include "G4OpenGLViewer.hh" #include "G4OpenGLSceneHandler.hh" #include "G4OpenGLTransform3D.hh" #include "G4Scene.hh" #include "G4VisExtent.hh" #include "G4LogicalVolume.hh" #include "G4VSolid.hh" #include "G4Point3D.hh" #include "G4Normal3D.hh" #include "G4Plane3D.hh" G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene): G4VViewer (scene, -1), background (G4Colour(0.,0.,0.)), transparency_enabled (true), antialiasing_enabled (false), haloing_enabled (false), fStartTime(-DBL_MAX), fEndTime(DBL_MAX), fFadeFactor(0.), fDisplayHeadTime(false), fDisplayHeadTimeX(-0.9), fDisplayHeadTimeY(-0.9), fDisplayHeadTimeSize(24.), fDisplayHeadTimeRed(0.), fDisplayHeadTimeGreen(1.), fDisplayHeadTimeBlue(1.), fDisplayLightFront(false), fDisplayLightFrontX(0.), fDisplayLightFrontY(0.), fDisplayLightFrontZ(0.), fDisplayLightFrontT(0.), fDisplayLightFrontRed(0.), fDisplayLightFrontGreen(1.), fDisplayLightFrontBlue(0.) { // Make changes to view parameters for OpenGL... fVP.SetAutoRefresh(true); fDefaultVP.SetAutoRefresh(true); // glClearColor (0.0, 0.0, 0.0, 0.0); // glClearDepth (1.0); // glDisable (GL_BLEND); // glDisable (GL_LINE_SMOOTH); // glDisable (GL_POLYGON_SMOOTH); } G4OpenGLViewer::~G4OpenGLViewer () {} void G4OpenGLViewer::InitializeGLView () { printf("G4OpenGLViewer::InitializeGLView () VVVVVVVVVVVVVVVVVVVVV \n"); glClearColor (0.0, 0.0, 0.0, 0.0); glClearDepth (1.0); glDisable (GL_BLEND); glDisable (GL_LINE_SMOOTH); glDisable (GL_POLYGON_SMOOTH); printf("G4OpenGLViewer::InitializeGLView () ^^^^^^^^^^^^^^^^^^^^ \n"); } void G4OpenGLViewer::ClearView () { glClearColor (background.GetRed(), background.GetGreen(), background.GetBlue(), 1.); glClearDepth (1.0); //Below line does not compile with Mesa includes. //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear (GL_COLOR_BUFFER_BIT); glClear (GL_DEPTH_BUFFER_BIT); glClear (GL_STENCIL_BUFFER_BIT); glFlush (); } void G4OpenGLViewer::SetView () { // Calculates view representation based on extent of object being // viewed and (initial) viewpoint. (Note: it can change later due // to user interaction via visualization system's GUI.) // Lighting. GLfloat lightPosition [4]; lightPosition [0] = fVP.GetActualLightpointDirection().x(); lightPosition [1] = fVP.GetActualLightpointDirection().y(); lightPosition [2] = fVP.GetActualLightpointDirection().z(); lightPosition [3] = 0.; // Light position is "true" light direction, so must come after gluLookAt. GLfloat ambient [] = { 0.2, 0.2, 0.2, 1.}; GLfloat diffuse [] = { 0.8, 0.8, 0.8, 1.}; glEnable (GL_LIGHT0); glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse); // Get radius of scene, etc. // Note that this procedure properly takes into account zoom, dolly and pan. const G4Point3D targetPoint = fSceneHandler.GetScene()->GetStandardTargetPoint() + fVP.GetCurrentTargetPoint (); G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius(); if(radius<=0.) radius = 1.; const G4double cameraDistance = fVP.GetCameraDistance (radius); const G4Point3D cameraPosition = targetPoint + cameraDistance * fVP.GetViewpointDirection().unit(); const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius); const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius); const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius); const GLdouble left = -right; const GLdouble bottom = left; const GLdouble top = right; glMatrixMode (GL_PROJECTION); // set up Frustum. glLoadIdentity(); const G4Vector3D scale = fVP.GetScaleFactor(); glScaled(scale.x(),scale.y(),scale.z()); if (fVP.GetFieldHalfAngle() == 0.) { glOrtho (left, right, bottom, top, pnear, pfar); } else { glFrustum (left, right, bottom, top, pnear, pfar); } glMatrixMode (GL_MODELVIEW); // apply further transformations to scene. glLoadIdentity(); const G4Normal3D& upVector = fVP.GetUpVector (); G4Point3D gltarget; if (cameraDistance > 1.e-6 * radius) { gltarget = targetPoint; } else { gltarget = targetPoint - radius * fVP.GetViewpointDirection().unit(); } const G4Point3D& pCamera = cameraPosition; // An alias for brevity. gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint. gltarget.x(), gltarget.y(), gltarget.z(), // Target point. upVector.x(), upVector.y(), upVector.z()); // Up vector. // Light position is "true" light direction, so must come after gluLookAt. glLightfv (GL_LIGHT0, GL_POSITION, lightPosition); // OpenGL no longer seems to reconstruct clipped edges, so, when the // BooleanProcessor is up to it, abandon this and use generic // clipping in G4OpenGLSceneHandler::CreateSectionPolyhedron. Also, // force kernel visit on change of clipping plane in // G4OpenGLStoredViewer::CompareForKernelVisit. if (fVP.IsSection () ) { // pair of back to back clip planes. const G4Plane3D& s = fVP.GetSectionPlane (); double sArray[4]; sArray[0] = s.a(); sArray[1] = s.b(); sArray[2] = s.c(); sArray[3] = s.d() + radius * 1.e-05; glClipPlane (GL_CLIP_PLANE0, sArray); glEnable (GL_CLIP_PLANE0); sArray[0] = -s.a(); sArray[1] = -s.b(); sArray[2] = -s.c(); sArray[3] = -s.d() + radius * 1.e-05; glClipPlane (GL_CLIP_PLANE1, sArray); glEnable (GL_CLIP_PLANE1); } else { glDisable (GL_CLIP_PLANE0); glDisable (GL_CLIP_PLANE1); } const G4Planes& cutaways = fVP.GetCutawayPlanes(); size_t nPlanes = cutaways.size(); if (fVP.IsCutaway() && fVP.GetCutawayMode() == G4ViewParameters::cutawayIntersection && nPlanes > 0) { double a[4]; a[0] = cutaways[0].a(); a[1] = cutaways[0].b(); a[2] = cutaways[0].c(); a[3] = cutaways[0].d(); glClipPlane (GL_CLIP_PLANE2, a); glEnable (GL_CLIP_PLANE2); if (nPlanes > 1) { a[0] = cutaways[1].a(); a[1] = cutaways[1].b(); a[2] = cutaways[1].c(); a[3] = cutaways[1].d(); glClipPlane (GL_CLIP_PLANE3, a); glEnable (GL_CLIP_PLANE3); } if (nPlanes > 2) { a[0] = cutaways[2].a(); a[1] = cutaways[2].b(); a[2] = cutaways[2].c(); a[3] = cutaways[2].d(); glClipPlane (GL_CLIP_PLANE4, a); glEnable (GL_CLIP_PLANE4); } } else { glDisable (GL_CLIP_PLANE2); glDisable (GL_CLIP_PLANE3); glDisable (GL_CLIP_PLANE4); } // Background. background = fVP.GetBackgroundColour (); } void G4OpenGLViewer::HaloingFirstPass () { //To perform haloing, first Draw all information to the depth buffer //alone, using a chunky line width, and then Draw all info again, to //the colour buffer, setting a thinner line width an the depth testing //function to less than or equal, so if two lines cross, the one //passing behind the other will not pass the depth test, and so not //get rendered either side of the infront line for a short distance. //First, disable writing to the colo(u)r buffer... glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //Now enable writing to the depth buffer... glDepthMask (GL_TRUE); glDepthFunc (GL_LESS); glClearDepth (1.0); //Finally, set the line width to something wide... glLineWidth (3.0); } void G4OpenGLViewer::HaloingSecondPass () { //And finally, turn the colour buffer back on with a sesible line width... glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthFunc (GL_LEQUAL); glLineWidth (1.0); } #endif