source: trunk/geant4/visualization/OpenGL/old-src/G4OpenGLStoredSceneHandler.cc@ 585

Last change on this file since 585 was 562, checked in by garnier, 18 years ago

r565@mac-90108: laurentgarnier | 2007-08-14 14:18:03 +0200
mise a jour suite au plantage de svk (cheksum error) suite au crash du DD en juin

  • Property svn:mime-type set to text/cpp
File size: 12.6 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4OpenGLStoredSceneHandler.cc,v 1.31 2006/08/30 11:43:57 allison Exp $
28// GEANT4 tag $Name: geant4-08-02-patch-01 $
29//
30//
31// Andrew Walkden 10th February 1997
32// OpenGL stored scene - creates OpenGL display lists.
33
34#ifdef G4VIS_BUILD_OPENGL_DRIVER
35
36// Included here - problems with HP compiler if not before other includes?
37#include "G4NURBS.hh"
38
39// Here follows a special for Mesa, the OpenGL emulator. Does not affect
40// other OpenGL's, as far as I'm aware. John Allison 18/9/96.
41#define CENTERLINE_CLPP /* CenterLine C++ workaround: */
42// Also seems to be required for HP's CC and AIX xlC, at least.
43
44#include "G4OpenGLStoredSceneHandler.hh"
45
46#include "G4PhysicalVolumeModel.hh"
47#include "G4VPhysicalVolume.hh"
48#include "G4Polyline.hh"
49#include "G4Polymarker.hh"
50#include "G4Circle.hh"
51#include "G4Square.hh"
52
53G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler (G4VGraphicsSystem& system,
54 const G4String& name):
55G4OpenGLSceneHandler (system, fSceneIdCount++, name),
56fMemoryForDisplayLists (true),
57fAddPrimitivePreambleNestingDepth (0),
58fTopPODL (0)
59{}
60
61G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
62{}
63
64void G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible)
65{
66 // Track nesting depth to avoid recursive calls, for example, from a
67 // G4Polymarker that invokes a G4Circle...
68 fAddPrimitivePreambleNestingDepth++;
69 if (fAddPrimitivePreambleNestingDepth > 1) return;
70
71 const G4Colour& c = GetColour (visible);
72
73 if (fMemoryForDisplayLists && fReadyForTransients) {
74
75 TO& to = fTOList.back(); // Transient object information.
76
77 // Get vis attributes - pick up defaults if none.
78 const G4VisAttributes* pVA =
79 fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
80
81 // Get time information from vis attributes.
82 to.fStartTime = pVA->GetStartTime();
83 to.fEndTime = pVA->GetEndTime();
84
85 // Keep colour out of (already started) display list so that it
86 // can be applied independently.
87 glEndList();
88 glDeleteLists(fDisplayListId, 1);
89 to.fColour = c;
90 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
91 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
92
93 } else {
94
95 // Make sure colour is set in other cases.
96 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
97 }
98}
99
100void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
101{
102 fAddPrimitivePreambleNestingDepth--;
103}
104
105void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
106{
107 AddPrimitivePreamble(polyline);
108 G4OpenGLSceneHandler::AddPrimitive(polyline);
109 AddPrimitivePostamble();
110}
111
112void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
113{
114 AddPrimitivePreamble(circle);
115 G4OpenGLSceneHandler::AddPrimitive(circle);
116 AddPrimitivePostamble();
117}
118
119void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
120{
121 AddPrimitivePreamble(square);
122 G4OpenGLSceneHandler::AddPrimitive(square);
123 AddPrimitivePostamble();
124}
125
126void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
127{
128 AddPrimitivePreamble(polymarker);
129 G4OpenGLSceneHandler::AddPrimitive(polymarker);
130 AddPrimitivePostamble();
131}
132
133void G4OpenGLStoredSceneHandler::BeginPrimitives
134(const G4Transform3D& objectTransformation) {
135
136 G4VSceneHandler::BeginPrimitives (objectTransformation);
137
138 if (fMemoryForDisplayLists) {
139 fDisplayListId = glGenLists (1);
140 if (!fDisplayListId) { // Could pre-allocate?
141 G4cout << "********************* WARNING! ********************\n"
142 <<"Unable to allocate any more display lists in OpenGL.\n "
143 << " Continuing drawing in IMMEDIATE MODE.\n"
144 << "***************************************************" << G4endl;
145 fMemoryForDisplayLists = false;
146 }
147 }
148 if (fMemoryForDisplayLists) {
149 if (fReadyForTransients) {
150 TO to(fDisplayListId, objectTransformation);
151 fTOList.push_back(to);
152 glDrawBuffer (GL_FRONT);
153 glPushMatrix();
154 G4OpenGLTransform3D oglt (objectTransformation);
155 glMultMatrixd (oglt.GetGLMatrix ());
156 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
157 }
158 else {
159 fPOList.push_back(PO(fDisplayListId, objectTransformation));
160 glNewList (fDisplayListId, GL_COMPILE);
161 }
162 } else {
163 glDrawBuffer (GL_FRONT);
164 glPushMatrix();
165 G4OpenGLTransform3D oglt (objectTransformation);
166 glMultMatrixd (oglt.GetGLMatrix ());
167 }
168}
169
170void G4OpenGLStoredSceneHandler::EndPrimitives () {
171 if (fMemoryForDisplayLists) {
172 glEndList();
173 }
174 if (fReadyForTransients || !fMemoryForDisplayLists) {
175 glPopMatrix();
176 glFlush ();
177 glDrawBuffer (GL_BACK);
178 }
179 G4VSceneHandler::EndPrimitives ();
180}
181
182void G4OpenGLStoredSceneHandler::BeginPrimitives2D()
183{
184 G4VSceneHandler::BeginPrimitives2D();
185
186 if (fMemoryForDisplayLists) {
187 fDisplayListId = glGenLists (1);
188 if (!fDisplayListId) { // Could pre-allocate?
189 G4cout << "********************* WARNING! ********************\n"
190 <<"Unable to allocate any more display lists in OpenGL.\n "
191 << " Continuing drawing in IMMEDIATE MODE.\n"
192 << "***************************************************" << G4endl;
193 fMemoryForDisplayLists = false;
194 }
195 }
196 if (fMemoryForDisplayLists) {
197 if (fReadyForTransients) {
198 fTOList.push_back(TO(fDisplayListId));
199 glDrawBuffer (GL_FRONT);
200 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
201 }
202 else {
203 fPOList.push_back(PO(fDisplayListId));
204 glNewList (fDisplayListId, GL_COMPILE);
205 }
206 } else {
207 glDrawBuffer (GL_FRONT);
208 }
209 // Push current 3D world matrices and load identity to define screen
210 // coordinates...
211 glMatrixMode (GL_PROJECTION);
212 glPushMatrix();
213 glLoadIdentity();
214 glOrtho (-1., 1., -1., 1., -DBL_MAX, DBL_MAX);
215 glMatrixMode (GL_MODELVIEW);
216 glPushMatrix();
217 glLoadIdentity();
218}
219
220void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
221{
222 // Pop current 3D world matrices back again...
223 glMatrixMode (GL_PROJECTION);
224 glPopMatrix();
225 glMatrixMode (GL_MODELVIEW);
226 glPopMatrix();
227
228 if (fMemoryForDisplayLists) {
229 glEndList();
230 }
231 if (fReadyForTransients || !fMemoryForDisplayLists) {
232 glFlush ();
233 glDrawBuffer (GL_BACK);
234 }
235 G4VSceneHandler::EndPrimitives2D ();
236}
237
238void G4OpenGLStoredSceneHandler::BeginModeling () {
239 G4VSceneHandler::BeginModeling();
240 ClearStore(); // ...and all that goes with it.
241 /* Debug...
242 fDisplayListId = glGenLists (1);
243 G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
244 */
245}
246
247void G4OpenGLStoredSceneHandler::EndModeling () {
248 // Make a List which calls the other lists.
249 fTopPODL = glGenLists (1);
250 if (!fTopPODL) {
251 G4cout <<
252 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
253 " display List for fTopPODL - try OpenGL Immediated mode."
254 << G4endl;
255 }
256 else {
257 glNewList (fTopPODL, GL_COMPILE_AND_EXECUTE); {
258 for (size_t i = 0; i < fPOList.size (); i++) {
259 glPushMatrix();
260 G4OpenGLTransform3D oglt (fPOList[i].fTransform);
261 glMultMatrixd (oglt.GetGLMatrix ());
262 glCallList (fPOList[i].fDisplayListId);
263 glPopMatrix();
264 }
265 }
266 glEndList ();
267 }
268
269 G4VSceneHandler::EndModeling ();
270
271 /* Debug...
272 fDisplayListId = glGenLists (1);
273 G4cout << "OGL::fDisplayListId (end): " << fDisplayListId << G4endl;
274 */
275}
276
277void G4OpenGLStoredSceneHandler::ClearStore () {
278
279 G4VSceneHandler::ClearStore (); // Sets need kernel visit, etc.
280
281 // Delete OpenGL permanent display lists.
282 for (size_t i = 0; i < fPOList.size (); i++)
283 glDeleteLists (fPOList[i].fDisplayListId, 1);
284 if (fTopPODL) glDeleteLists (fTopPODL, 1);
285 fTopPODL = 0;
286
287 // Clear other lists, dictionary, etc.
288 fPOList.clear ();
289 fSolidMap.clear ();
290
291 // ...and clear transient store...
292 for (size_t i = 0; i < fTOList.size (); i++)
293 glDeleteLists(fTOList[i].fDisplayListId, 1);
294 fTOList.clear ();
295}
296
297void G4OpenGLStoredSceneHandler::ClearTransientStore () {
298
299 G4VSceneHandler::ClearTransientStore ();
300
301 // Delete OpenGL transient display lists and Transient Objects themselves.
302 for (size_t i = 0; i < fTOList.size (); i++)
303 glDeleteLists(fTOList[i].fDisplayListId, 1);
304 fTOList.clear ();
305
306 // Make sure screen corresponds to graphical database...
307 if (fpViewer) {
308 fpViewer -> SetView ();
309 fpViewer -> ClearView ();
310 fpViewer -> DrawView ();
311 }
312}
313
314void G4OpenGLStoredSceneHandler::RequestPrimitives (const G4VSolid& solid)
315{
316 if (fReadyForTransients) {
317 // Always draw transient solids, e.g., hits represented as solids.
318 // (As we have no control over the order of drawing of transient
319 // objects, we cannot do anything about transparent ones, as
320 // below, so always draw them.)
321 G4VSceneHandler::RequestPrimitives (solid);
322 return;
323 }
324
325 // For non-transient (run-duration) objects, ensure transparent
326 // objects are drawn last. The problem of
327 // blending/transparency/alpha is quite a tricky one - see History
328 // of opengl-V07-01-01/2/3.
329 // Get vis attributes - pick up defaults if none.
330 const G4VisAttributes* pVA =
331 fpViewer -> GetApplicableVisAttributes(fpVisAttribs);
332 const G4Colour& c = pVA -> GetColour ();
333 G4double opacity = c.GetAlpha ();
334
335 if (!fSecondPass) {
336 G4bool transparency_enabled = true;
337 G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
338 if (pViewer) transparency_enabled = pViewer->transparency_enabled;
339 if (transparency_enabled && opacity < 1.) {
340 // On first pass, transparent objects are not drawn, but flag is set...
341 fSecondPassRequested = true;
342 return;
343 }
344 }
345
346 // On second pass, opaque objects are not drwan...
347 if (fSecondPass && opacity >= 1.) return;
348
349 G4PhysicalVolumeModel* pPVModel =
350 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
351
352 if (pPVModel) {
353 // If part of the geometry hierarchy, i.e., from a
354 // G4PhysicalVolumeModel, check if a display list already exists for
355 // this solid, re-use it if possible. We could be smarter, and
356 // recognise repeated branches of the geometry hierarchy, for
357 // example. But this algorithm should be secure, I think...
358 const G4VSolid* pSolid = &solid;
359 EAxis axis = kRho;
360 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
361 if (pCurrentPV -> IsReplicated ()) {
362 G4int nReplicas;
363 G4double width;
364 G4double offset;
365 G4bool consuming;
366 pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
367 }
368 // Provided it is not parametrised (because if so, the
369 // solid's parameters might have been changed)...
370 if (!(pCurrentPV -> IsParameterised ()) &&
371 // Provided it is not replicated radially (because if so, the
372 // solid's parameters will have been changed)...
373 !(pCurrentPV -> IsReplicated () && axis == kRho) &&
374 // ...and if the solid has already been rendered...
375 (fSolidMap.find (pSolid) != fSolidMap.end ())) {
376 fDisplayListId = fSolidMap [pSolid];
377 fPOList.push_back(PO(fDisplayListId,*fpObjectTransformation));
378 }
379 else {
380 G4VSceneHandler::RequestPrimitives (solid);
381 fSolidMap [pSolid] = fDisplayListId;
382 }
383 return;
384 }
385
386 // Otherwise invoke base class method...
387 G4VSceneHandler::RequestPrimitives (solid);
388}
389
390G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
391
392#endif
Note: See TracBrowser for help on using the repository browser.