source: trunk/source/visualization/OpenGL/src/G4OpenGLStoredSceneHandler.cc@ 1213

Last change on this file since 1213 was 1160, checked in by garnier, 16 years ago

mise en place de Vis dans UI

  • Property svn:mime-type set to text/cpp
File size: 15.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: G4OpenGLStoredSceneHandler.cc,v 1.40 2009/02/04 16:48:41 lgarnier Exp $
28// GEANT4 tag $Name: $
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 "G4LogicalVolume.hh"
49#include "G4Polyline.hh"
50#include "G4Polymarker.hh"
51#include "G4Text.hh"
52#include "G4Circle.hh"
53#include "G4Square.hh"
54#include "G4Polyhedron.hh"
55#include "G4AttHolder.hh"
56#include "G4OpenGLTransform3D.hh"
57#include "G4OpenGLViewer.hh"
58
59G4OpenGLStoredSceneHandler::PO::PO
60(G4int id,
61 const G4Transform3D& tr):
62 fDisplayListId(id),
63 fTransform(tr),
64 fPickName(0)
65{}
66
67G4OpenGLStoredSceneHandler::TO::TO
68(G4int id,
69 const G4Transform3D& tr):
70 fDisplayListId(id),
71 fTransform(tr),
72 fPickName(0),
73 fStartTime(-DBL_MAX),
74 fEndTime(DBL_MAX)
75{}
76
77G4OpenGLStoredSceneHandler::G4OpenGLStoredSceneHandler
78(G4VGraphicsSystem& system,
79 const G4String& name):
80G4OpenGLSceneHandler (system, fSceneIdCount++, name),
81fMemoryForDisplayLists (true),
82fAddPrimitivePreambleNestingDepth (0),
83fTopPODL (0)
84{}
85
86G4OpenGLStoredSceneHandler::~G4OpenGLStoredSceneHandler ()
87{}
88
89void G4OpenGLStoredSceneHandler::AddPrimitivePreamble(const G4Visible& visible)
90{
91 // Track nesting depth to avoid recursive calls, for example, from a
92 // G4Polymarker that invokes a G4Circle...
93 fAddPrimitivePreambleNestingDepth++;
94 if (fAddPrimitivePreambleNestingDepth > 1) return;
95
96 // Because of our need to control colour of transients (display by
97 // time fading), display lists may only cover a single primitive.
98 // So display list setup is here.
99
100 if (fpViewer->GetViewParameters().IsPicking()) {
101 fPickMap[++fPickName] = 0;
102 }
103
104 const G4Colour& c = GetColour (visible);
105
106 if (fMemoryForDisplayLists) {
107 fDisplayListId = glGenLists (1);
108 if (glGetError() == GL_OUT_OF_MEMORY) { // Could pre-allocate?
109 G4cout <<
110 "********************* WARNING! ********************"
111 "\nUnable to allocate any more display lists in OpenGL."
112 "\n Continuing drawing in IMMEDIATE MODE."
113 "\n***************************************************"
114 << G4endl;
115 fMemoryForDisplayLists = false;
116 }
117 }
118 if (fMemoryForDisplayLists) {
119 if (fReadyForTransients) {
120 TO to(fDisplayListId, *fpObjectTransformation);
121 to.fPickName = fPickName;
122 to.fColour = c;
123 const G4VisAttributes* pVA =
124 fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
125 to.fStartTime = pVA->GetStartTime();
126 to.fEndTime = pVA->GetEndTime();
127 fTOList.push_back(to);
128 glDrawBuffer (GL_FRONT);
129 glPushMatrix();
130 G4OpenGLTransform3D oglt (*fpObjectTransformation);
131 glMultMatrixd (oglt.GetGLMatrix ());
132 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
133 glNewList (fDisplayListId, GL_COMPILE_AND_EXECUTE);
134 }
135 else {
136 PO po(fDisplayListId, *fpObjectTransformation);
137 po.fPickName = fPickName;
138 fPOList.push_back(po);
139 glNewList (fDisplayListId, GL_COMPILE);
140 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
141 }
142 } else {
143 glDrawBuffer (GL_FRONT);
144 glPushMatrix();
145 G4OpenGLTransform3D oglt (*fpObjectTransformation);
146 glMultMatrixd (oglt.GetGLMatrix ());
147 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
148 }
149
150 if (fProcessing2D) {
151 // Push current 3D world matrices and load identity to define screen
152 // coordinates...
153 glMatrixMode (GL_PROJECTION);
154 glPushMatrix();
155 glLoadIdentity();
156 glOrtho (-1., 1., -1., 1., -G4OPENGL_FLT_BIG, G4OPENGL_FLT_BIG);
157 glMatrixMode (GL_MODELVIEW);
158 glPushMatrix();
159 glLoadIdentity();
160 G4OpenGLTransform3D oglt (*fpObjectTransformation);
161 glMultMatrixd (oglt.GetGLMatrix ());
162 glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
163 }
164}
165
166void G4OpenGLStoredSceneHandler::AddPrimitivePostamble()
167{
168 if (fProcessing2D) {
169 // Pop current 3D world matrices back again...
170 glMatrixMode (GL_PROJECTION);
171 glPopMatrix();
172 glMatrixMode (GL_MODELVIEW);
173 glPopMatrix();
174 }
175
176 // if ((glGetError() == GL_TABLE_TOO_LARGE) || (glGetError() == GL_OUT_OF_MEMORY)) { // Could close?
177 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
178 G4cout <<
179 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
180 " display List for fTopPODL - try OpenGL Immediated mode."
181 << G4endl;
182 }
183 if (fMemoryForDisplayLists) {
184 glEndList();
185 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
186 G4cout <<
187 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
188 " display List for fTopPODL - try OpenGL Immediated mode."
189 << G4endl;
190 }
191 }
192 if (fReadyForTransients || !fMemoryForDisplayLists) {
193 glPopMatrix();
194 glFlush ();
195 glDrawBuffer (GL_BACK);
196 }
197 fAddPrimitivePreambleNestingDepth--;
198}
199
200void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyline& polyline)
201{
202 AddPrimitivePreamble(polyline);
203 G4OpenGLSceneHandler::AddPrimitive(polyline);
204 AddPrimitivePostamble();
205}
206
207void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
208{
209 AddPrimitivePreamble(polymarker);
210 G4OpenGLSceneHandler::AddPrimitive(polymarker);
211 AddPrimitivePostamble();
212}
213
214void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Text& text)
215{
216 // Note: colour is still handled in
217 // G4OpenGLSceneHandler::AddPrimitive(const G4Text&), so it still
218 // gets into the display list
219 AddPrimitivePreamble(text);
220 G4OpenGLSceneHandler::AddPrimitive(text);
221 AddPrimitivePostamble();
222}
223
224void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Circle& circle)
225{
226 AddPrimitivePreamble(circle);
227 G4OpenGLSceneHandler::AddPrimitive(circle);
228 AddPrimitivePostamble();
229}
230
231void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Square& square)
232{
233 AddPrimitivePreamble(square);
234 G4OpenGLSceneHandler::AddPrimitive(square);
235 AddPrimitivePostamble();
236}
237
238void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Scale& scale)
239{
240 // Let base class split into primitives.
241 G4OpenGLSceneHandler::AddPrimitive(scale);
242}
243
244void G4OpenGLStoredSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
245{
246 // Note: colour is still handled in
247 // G4OpenGLSceneHandler::AddPrimitive(const G4Polyhedron&), so it still
248 // gets into the display list
249 AddPrimitivePreamble(polyhedron);
250 G4OpenGLSceneHandler::AddPrimitive(polyhedron);
251 AddPrimitivePostamble();
252}
253
254void G4OpenGLStoredSceneHandler::AddPrimitive (const G4NURBS& nurbs)
255{
256 // Note: colour is still handled in
257 // G4OpenGLSceneHandler::AddPrimitive(const G4NURBS&), so it still
258 // gets into the display list
259 AddPrimitivePreamble(nurbs);
260 G4OpenGLSceneHandler::AddPrimitive(nurbs);
261 AddPrimitivePostamble();
262}
263
264void G4OpenGLStoredSceneHandler::BeginPrimitives
265(const G4Transform3D& objectTransformation)
266{
267 G4OpenGLSceneHandler::BeginPrimitives (objectTransformation);
268
269 // Display list setup moved to AddPrimitivePreamble. See notes there.
270}
271
272void G4OpenGLStoredSceneHandler::EndPrimitives ()
273{
274 G4OpenGLSceneHandler::EndPrimitives ();
275}
276
277void G4OpenGLStoredSceneHandler::BeginPrimitives2D
278(const G4Transform3D& objectTransformation)
279{
280 G4OpenGLSceneHandler::BeginPrimitives2D(objectTransformation);
281}
282
283void G4OpenGLStoredSceneHandler::EndPrimitives2D ()
284{
285 G4OpenGLSceneHandler::EndPrimitives2D ();
286}
287
288void G4OpenGLStoredSceneHandler::BeginModeling () {
289 G4VSceneHandler::BeginModeling();
290 ClearStore(); // ...and all that goes with it.
291 /* Debug...
292 fDisplayListId = glGenLists (1);
293 G4cout << "OGL::fDisplayListId (start): " << fDisplayListId << G4endl;
294 */
295}
296
297void G4OpenGLStoredSceneHandler::EndModeling () {
298 // Make a List which calls the other lists.
299 fTopPODL = glGenLists (1);
300 if (glGetError() == GL_OUT_OF_MEMORY) { // Could pre-allocate?
301 G4cout <<
302 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
303 " display List for fTopPODL - try OpenGL Immediated mode."
304 << G4endl;
305 } else {
306 glNewList (fTopPODL, GL_COMPILE_AND_EXECUTE); {
307 for (size_t i = 0; i < fPOList.size (); i++) {
308 glPushMatrix();
309 G4OpenGLTransform3D oglt (fPOList[i].fTransform);
310 glMultMatrixd (oglt.GetGLMatrix ());
311 if (fpViewer->GetViewParameters().IsPicking())
312 glLoadName(fPOList[i].fPickName);
313 glCallList (fPOList[i].fDisplayListId);
314 glPopMatrix();
315 }
316 }
317 glEndList ();
318 if (glGetError() == GL_OUT_OF_MEMORY) { // Could close?
319 G4cout <<
320 "ERROR: G4OpenGLStoredSceneHandler::EndModeling: Failure to allocate"
321 " display List for fTopPODL - try OpenGL Immediated mode."
322 << G4endl;
323 }
324 }
325
326 G4VSceneHandler::EndModeling ();
327
328 /* Debug...
329 fDisplayListId = glGenLists (1);
330 G4cout << "OGL::fDisplayListId (end): " << fDisplayListId << G4endl;
331 */
332}
333
334void G4OpenGLStoredSceneHandler::ClearStore () {
335
336 G4VSceneHandler::ClearStore (); // Sets need kernel visit, etc.
337
338 // Delete OpenGL permanent display lists.
339 for (size_t i = 0; i < fPOList.size (); i++)
340 glDeleteLists (fPOList[i].fDisplayListId, 1);
341 if (fTopPODL) glDeleteLists (fTopPODL, 1);
342 fTopPODL = 0;
343
344 // Clear other lists, dictionary, etc.
345 fPOList.clear ();
346 fSolidMap.clear ();
347 ClearAndDestroyAtts();
348
349 // ...and clear transient store...
350 for (size_t i = 0; i < fTOList.size (); i++)
351 glDeleteLists(fTOList[i].fDisplayListId, 1);
352 fTOList.clear ();
353}
354
355void G4OpenGLStoredSceneHandler::ClearTransientStore () {
356
357 G4VSceneHandler::ClearTransientStore ();
358
359 // Delete OpenGL transient display lists and Transient Objects themselves.
360 for (size_t i = 0; i < fTOList.size (); i++)
361 glDeleteLists(fTOList[i].fDisplayListId, 1);
362 fTOList.clear ();
363
364 // Make sure screen corresponds to graphical database...
365 if (fpViewer) {
366 fpViewer -> SetView ();
367 fpViewer -> ClearView ();
368 fpViewer -> DrawView ();
369 }
370}
371
372void G4OpenGLStoredSceneHandler::RequestPrimitives (const G4VSolid& solid)
373{
374 if (fReadyForTransients) {
375 // Always draw transient solids, e.g., hits represented as solids.
376 // (As we have no control over the order of drawing of transient
377 // objects, we cannot do anything about transparent ones, as
378 // below, so always draw them.)
379 G4VSceneHandler::RequestPrimitives (solid);
380 return;
381 }
382
383 // For non-transient (run-duration) objects, ensure transparent
384 // objects are drawn last. The problem of
385 // blending/transparency/alpha is quite a tricky one - see History
386 // of opengl-V07-01-01/2/3.
387 // Get vis attributes - pick up defaults if none.
388 const G4VisAttributes* pVA =
389 fpViewer -> GetApplicableVisAttributes(fpVisAttribs);
390 const G4Colour& c = pVA -> GetColour ();
391 G4double opacity = c.GetAlpha ();
392
393 if (!fSecondPass) {
394 G4bool transparency_enabled = true;
395 G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
396 if (pViewer) transparency_enabled = pViewer->transparency_enabled;
397 if (transparency_enabled && opacity < 1.) {
398 // On first pass, transparent objects are not drawn, but flag is set...
399 fSecondPassRequested = true;
400 return;
401 }
402 }
403
404 // On second pass, opaque objects are not drwan...
405 if (fSecondPass && opacity >= 1.) return;
406
407 G4PhysicalVolumeModel* pPVModel =
408 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
409
410 if (pPVModel) {
411 // If part of the geometry hierarchy, i.e., from a
412 // G4PhysicalVolumeModel, check if a display list already exists for
413 // this solid, re-use it if possible. We could be smarter, and
414 // recognise repeated branches of the geometry hierarchy, for
415 // example. But this algorithm should be secure, I think...
416 const G4VSolid* pSolid = &solid;
417 EAxis axis = kRho;
418 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
419 if (pCurrentPV -> IsReplicated ()) {
420 G4int nReplicas;
421 G4double width;
422 G4double offset;
423 G4bool consuming;
424 pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
425 }
426 // Provided it is not parametrised (because if so, the
427 // solid's parameters might have been changed)...
428 if (!(pCurrentPV -> IsParameterised ()) &&
429 // Provided it is not replicated radially (because if so, the
430 // solid's parameters will have been changed)...
431 !(pCurrentPV -> IsReplicated () && axis == kRho) &&
432 // ...and if the solid has already been rendered...
433 (fSolidMap.find (pSolid) != fSolidMap.end ())) {
434 fDisplayListId = fSolidMap [pSolid];
435 PO po(fDisplayListId,*fpObjectTransformation);
436 if (fpViewer->GetViewParameters().IsPicking()) {
437 G4AttHolder* holder = new G4AttHolder;
438 // Load G4Atts from G4VisAttributes, if any...
439 const G4VisAttributes* va = pPVModel->GetCurrentLV()->GetVisAttributes();
440 if (va) {
441 const std::map<G4String,G4AttDef>* vaDefs = va->GetAttDefs();
442 if (vaDefs) holder->AddAtts(va->CreateAttValues(), vaDefs);
443 }
444 // Load G4Atts from G4PhysicalVolumeModel...
445 const std::map<G4String,G4AttDef>* defs = pPVModel->GetAttDefs();
446 if (defs) holder->AddAtts(pPVModel->CreateCurrentAttValues(), defs);
447 fPickMap[++fPickName] = holder;
448 po.fPickName = fPickName;
449 }
450 fPOList.push_back(po);
451 }
452 else {
453 G4VSceneHandler::RequestPrimitives (solid);
454 fSolidMap [pSolid] = fDisplayListId;
455 }
456 return;
457 }
458
459 // Otherwise invoke base class method...
460 G4VSceneHandler::RequestPrimitives (solid);
461}
462
463G4int G4OpenGLStoredSceneHandler::fSceneIdCount = 0;
464
465#endif
Note: See TracBrowser for help on using the repository browser.