1 /*=========================================================================
2 
3 Program:   Visualization Toolkit
4 Module:    vtkOpenGLRenderer.cxx
5 
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkOpenGLRenderer.h"
16 
17 #include "vtkCuller.h"
18 #include "vtkLightCollection.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkOpenGLCamera.h"
21 #include "vtkOpenGLLight.h"
22 #include "vtkOpenGLProperty.h"
23 #include "vtkRenderWindow.h"
24 #include "vtkOpenGLRenderWindow.h"
25 #include "vtkOpenGLExtensionManager.h"
26 #include "vtkgl.h" // vtkgl namespace
27 #include "vtkImageImport.h"
28 #include "vtkPNGWriter.h"
29 #include "vtkOpenGLTexture.h"
30 #include "vtkTimerLog.h"
31 #include "vtkRenderPass.h"
32 #include "vtkRenderState.h"
33 
34 #include "vtkOpenGL.h"
35 #include "vtkOpenGLError.h"
36 
37 #include "vtkShaderProgram2.h"
38 
39 #include <math.h>
40 #include <cassert>
41 #include <list>
42 
43 class vtkGLPickInfo
44 {
45 public:
46   GLuint* PickBuffer;
47   GLuint PickedId;
48   GLuint NumPicked;
49 };
50 
51 vtkStandardNewMacro(vtkOpenGLRenderer);
52 
53 vtkCxxSetObjectMacro(vtkOpenGLRenderer,ShaderProgram,vtkShaderProgram2);
54 vtkCxxSetObjectMacro(vtkOpenGLRenderer, Pass, vtkRenderPass);
55 
56 #define VTK_MAX_LIGHTS 8
57 
58 // List of rgba layers, id are 2D rectangle texture Ids.
59 class vtkOpenGLRendererLayerList
60 {
61 public:
62   std::list<GLuint> List;
63 };
64 
65 extern const char *vtkOpenGLRenderer_PeelingFS;
66 
vtkOpenGLRenderer()67 vtkOpenGLRenderer::vtkOpenGLRenderer()
68 {
69   this->PickInfo = new vtkGLPickInfo;
70   this->NumberOfLightsBound = 0;
71   this->PickInfo->PickBuffer = 0;
72   this->PickInfo->PickedId = 0;
73   this->PickInfo->NumPicked = 0;
74   this->PickedZ = 0;
75 
76   this->DepthPeelingIsSupported=0;
77   this->DepthPeelingIsSupportedChecked=0;
78   this->LayerList=0;
79   this->OpaqueLayerZ=0;
80   this->TransparentLayerZ=0;
81   this->ProgramShader=0;
82   this->DepthFormat=0;
83   this->DepthPeelingHigherLayer=0;
84 
85   this->ShaderProgram=0;
86   this->BackgroundTexture = 0;
87   this->Pass = 0;
88 }
89 
90 // Internal method temporarily removes lights before reloading them
91 // into graphics pipeline.
ClearLights(void)92 void vtkOpenGLRenderer::ClearLights (void)
93 {
94   vtkOpenGLClearErrorMacro();
95 
96   short curLight;
97   float Info[4];
98 
99   // define a lighting model and set up the ambient light.
100   // use index 11 for the heck of it. Doesn't matter except for 0.
101 
102   // update the ambient light
103   Info[0] = this->Ambient[0];
104   Info[1] = this->Ambient[1];
105   Info[2] = this->Ambient[2];
106   Info[3] = 1.0;
107   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Info);
108 
109   if ( this->TwoSidedLighting )
110     {
111     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
112     }
113   else
114     {
115     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
116     }
117 
118   // now delete all the old lights
119   for (curLight = GL_LIGHT0; curLight < GL_LIGHT0 + VTK_MAX_LIGHTS; curLight++)
120     {
121     glDisable(static_cast<GLenum>(curLight));
122     }
123 
124   this->NumberOfLightsBound = 0;
125 
126   vtkOpenGLCheckErrorMacro("failed ater ClearLights");
127 }
128 
129 // Ask lights to load themselves into graphics pipeline.
UpdateLights()130 int vtkOpenGLRenderer::UpdateLights ()
131 {
132   vtkOpenGLClearErrorMacro();
133 
134   vtkLight *light;
135   short curLight;
136   float status;
137   int count;
138 
139   // Check if a light is on. If not then make a new light.
140   count = 0;
141   curLight= this->NumberOfLightsBound + GL_LIGHT0;
142 
143   vtkCollectionSimpleIterator sit;
144   for(this->Lights->InitTraversal(sit);
145       (light = this->Lights->GetNextLight(sit)); )
146     {
147     status = light->GetSwitch();
148     if ((status > 0.0)&& (curLight < (GL_LIGHT0+VTK_MAX_LIGHTS)))
149       {
150       curLight++;
151       count++;
152       }
153     }
154 
155   if( !count )
156     {
157     vtkDebugMacro(<<"No lights are on, creating one.");
158     this->CreateLight();
159     }
160 
161   count = 0;
162   curLight= this->NumberOfLightsBound + GL_LIGHT0;
163 
164   // set the matrix mode for lighting. ident matrix on viewing stack
165   glMatrixMode(GL_MODELVIEW);
166   glPushMatrix();
167 
168   for(this->Lights->InitTraversal(sit);
169       (light = this->Lights->GetNextLight(sit)); )
170     {
171 
172     status = light->GetSwitch();
173 
174     // if the light is on then define it and bind it.
175     // also make sure we still have room.
176     if ((status > 0.0)&& (curLight < (GL_LIGHT0+VTK_MAX_LIGHTS)))
177       {
178       light->Render(this,curLight);
179       glEnable(static_cast<GLenum>(curLight));
180 
181       // increment the current light by one
182       curLight++;
183       count++;
184       }
185     }
186 
187   this->NumberOfLightsBound = curLight - GL_LIGHT0;
188 
189   glPopMatrix();
190   glEnable(GL_LIGHTING);
191 
192   vtkOpenGLCheckErrorMacro("failed after UpdateLights");
193 
194   return count;
195 }
196 
197 // ----------------------------------------------------------------------------
198 // Description:
199 // Access to the OpenGL program shader uniform variable "useTexture" from the
200 // vtkOpenGLProperty or vtkOpenGLTexture.
GetUseTextureUniformVariable()201 int vtkOpenGLRenderer::GetUseTextureUniformVariable()
202 {
203   GLint result=vtkgl::GetUniformLocation(this->ProgramShader,"useTexture");
204   vtkOpenGLCheckErrorMacro("failed at glGetUniformLocation");
205   if(result==-1)
206     {
207     vtkErrorMacro(<<"useTexture is not a uniform variable");
208     }
209   return result;
210 }
211 
212 // ----------------------------------------------------------------------------
213 // Description:
214 // Access to the OpenGL program shader uniform variable "texture" from the
215 // vtkOpenGLProperty or vtkOpenGLTexture.
GetTextureUniformVariable()216 int vtkOpenGLRenderer::GetTextureUniformVariable()
217 {
218   GLint result=vtkgl::GetUniformLocation(this->ProgramShader,"texture");
219   vtkOpenGLCheckErrorMacro("failed at glGetUniformLocation");
220   if(result==-1)
221     {
222     vtkErrorMacro(<<"texture is not a uniform variable");
223     }
224   return result;
225 }
226 
227 // ----------------------------------------------------------------------------
228 // Description:
229 // Is rendering at translucent geometry stage using depth peeling and
230 // rendering a layer other than the first one? (Boolean value)
231 // If so, the uniform variables UseTexture and Texture can be set.
232 // (Used by vtkOpenGLProperty or vtkOpenGLTexture)
GetDepthPeelingHigherLayer()233 int vtkOpenGLRenderer::GetDepthPeelingHigherLayer()
234 {
235   return this->DepthPeelingHigherLayer;
236 }
237 
238 // ----------------------------------------------------------------------------
239 // Concrete open gl render method.
DeviceRender(void)240 void vtkOpenGLRenderer::DeviceRender(void)
241 {
242   vtkTimerLog::MarkStartEvent("OpenGL Dev Render");
243 
244   if(this->Pass!=0)
245     {
246     vtkRenderState s(this);
247     s.SetPropArrayAndCount(this->PropArray, this->PropArrayCount);
248     s.SetFrameBuffer(0);
249     this->Pass->Render(&s);
250     }
251   else
252     {
253     // Do not remove this MakeCurrent! Due to Start / End methods on
254     // some objects which get executed during a pipeline update,
255     // other windows might get rendered since the last time
256     // a MakeCurrent was called.
257     this->RenderWindow->MakeCurrent();
258     vtkOpenGLClearErrorMacro();
259 
260     // standard render method
261     this->ClearLights();
262 
263     this->UpdateCamera();
264     this->UpdateLightGeometry();
265     this->UpdateLights();
266 
267     // set matrix mode for actors
268     glMatrixMode(GL_MODELVIEW);
269 
270     this->UpdateGeometry();
271 
272     // clean up the model view matrix set up by the camera
273     glMatrixMode(GL_MODELVIEW);
274 
275     GLint mvDepth;
276     glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepth);
277     if (mvDepth>1)
278       {
279       glPopMatrix();
280       }
281 
282     vtkOpenGLCheckErrorMacro("failed after DeviceRender");
283     }
284 
285   vtkTimerLog::MarkEndEvent("OpenGL Dev Render");
286 }
287 
288 // ----------------------------------------------------------------------------
289 // Description:
290 // Render translucent polygonal geometry. Default implementation just call
291 // UpdateTranslucentPolygonalGeometry().
292 // Subclasses of vtkRenderer that can deal with depth peeling must
293 // override this method.
DeviceRenderTranslucentPolygonalGeometry()294 void vtkOpenGLRenderer::DeviceRenderTranslucentPolygonalGeometry()
295 {
296   vtkOpenGLClearErrorMacro();
297 
298   vtkOpenGLExtensionManager *extensions = NULL;
299 
300   if(this->UseDepthPeeling)
301     {
302     vtkOpenGLRenderWindow *context
303       = vtkOpenGLRenderWindow::SafeDownCast(this->RenderWindow);
304     if (!context)
305       {
306       vtkErrorMacro("OpenGL render window is required.")
307       return;
308       }
309     extensions = context->GetExtensionManager();
310 
311     if(!this->DepthPeelingIsSupportedChecked)
312       {
313       this->DepthPeelingIsSupportedChecked=1;
314 
315       int supports_GL_1_3=extensions->ExtensionSupported("GL_VERSION_1_3");
316       int supports_GL_1_4=extensions->ExtensionSupported("GL_VERSION_1_4");
317       int supports_GL_1_5=extensions->ExtensionSupported("GL_VERSION_1_5");
318       int supports_GL_2_0=extensions->ExtensionSupported("GL_VERSION_2_0");
319 
320       int supports_vertex_shader;
321       int supports_fragment_shader;
322       int supports_shader_objects;
323       if(supports_GL_2_0)
324         {
325         supports_vertex_shader=1;
326         supports_fragment_shader=1;
327         supports_shader_objects=1;
328         }
329       else
330         {
331         supports_vertex_shader=extensions->ExtensionSupported("GL_ARB_vertex_shader");
332         supports_fragment_shader=extensions->ExtensionSupported("GL_ARB_fragment_shader");
333         supports_shader_objects=extensions->ExtensionSupported("GL_ARB_shader_objects");
334         }
335       int supports_multitexture=supports_GL_1_3 || extensions->ExtensionSupported("GL_ARB_multitexture");
336       int supports_occlusion_query;
337       int supports_shadow_funcs;
338       if(supports_GL_1_5)
339         {
340         supports_occlusion_query=1;
341         supports_shadow_funcs=1;
342         }
343       else
344         {
345         supports_occlusion_query=extensions->ExtensionSupported("GL_ARB_occlusion_query");
346         supports_shadow_funcs=extensions->ExtensionSupported("GL_EXT_shadow_funcs");
347         }
348 
349       int supports_depth_texture;
350       int supports_shadow;
351       int supports_blend_func_separate;
352       if(supports_GL_1_4)
353         {
354         supports_depth_texture=1;
355         supports_blend_func_separate=1;
356         supports_shadow=1;
357         }
358       else
359         {
360         supports_depth_texture=extensions->ExtensionSupported("GL_ARB_depth_texture");
361         supports_shadow=extensions->ExtensionSupported("GL_ARB_shadow");
362         supports_blend_func_separate=extensions->ExtensionSupported("GL_EXT_blend_func_separate");
363         }
364 
365       int supports_GL_ARB_texture_rectangle=extensions->ExtensionSupported("GL_ARB_texture_rectangle");
366 
367       // spec claims it is GL_SGIS_texture_edge_clamp, reality shows it is
368       // GL_EXT_texture_edge_clamp on Nvidia.
369       // part of OpenGL 1.2 core
370       // there is no new function with this extension, we don't need to load
371       // it.
372       int supports_edge_clamp=extensions->ExtensionSupported("GL_VERSION_1_2");
373       if(!supports_edge_clamp)
374         {
375         supports_edge_clamp=extensions->ExtensionSupported("GL_SGIS_texture_edge_clamp");
376         if(!supports_edge_clamp)
377           {
378           // nvidia cards.
379           supports_edge_clamp=extensions->ExtensionSupported("GL_EXT_texture_edge_clamp");
380           }
381         }
382 
383       GLint alphaBits;
384       glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
385       int supportsAtLeast8AlphaBits=alphaBits>=8;
386 
387       // Mesa with "Offscreen" renderer (ie OS Mesa) supports depth peeling in
388       // all  versions tested 7.10, 8.0, 8.0.5, 9.0.3, 9.1.3, 9.1.4, 9.1.5
389       // Mesa version 7 with "Software Rasterizer" renderer all Opacity/Translucent
390       // ctests fail with depth peeling
391       // Mesa 9.2.0 with Gallium llvmpipe renderer some of these tests fail
392       // Mesa 8 with GMA945 renderer supports depth peeling
393       // ATI Radeon HD XXXXX on Windows chokes on PROXY_TEXTURE_RECTANGLE_ARB
394       // memory querries however if those are not used all the tests pass.
395       // ATI Radeon HD on Mac OSX PROXY_TEXTURE_RECTANGLE_ARB are fine but
396       // TestTranslucentLUTDepthPeeling fails. So leave it disabled on Apple
397       int driver_support
398         = (!(extensions->DriverIsATI()
399         && (extensions->GetDriverGLVersionMajor() < 3))
400         && (!extensions->DriverIsMesa()
401         || extensions->DriverGLRendererHas("Offscreen")
402         || (extensions->DriverVersionAtLeast(6,5,3)
403         && !extensions->DriverGLRendererIs("Software Rasterizer")
404         && !extensions->DriverGLRendererHasToken("llvmpipe"))))
405         || extensions->GetIgnoreDriverBugs("ATI/Mesa depth peeling bug.");
406 
407       this->DepthPeelingIsSupported =
408         supports_depth_texture &&
409         supports_shadow &&
410         supports_blend_func_separate &&
411         supports_shadow_funcs &&
412         supports_vertex_shader &&
413         supports_fragment_shader &&
414         supports_shader_objects &&
415         supports_occlusion_query &&
416         supports_multitexture &&
417         supports_GL_ARB_texture_rectangle &&
418         supports_edge_clamp &&
419         supportsAtLeast8AlphaBits &&
420         driver_support;
421 
422       if(this->DepthPeelingIsSupported)
423         {
424         vtkDebugMacro("depth peeling supported");
425         if(supports_GL_1_3)
426           {
427           extensions->LoadExtension("GL_VERSION_1_3");
428           }
429         else
430           {
431           extensions->LoadCorePromotedExtension("GL_ARB_multitexture");
432           }
433         // GL_ARB_depth_texture, GL_ARB_shadow and GL_EXT_shadow_funcs
434         // don't introduce new functions.
435         if(supports_GL_1_4)
436           {
437           extensions->LoadExtension("GL_VERSION_1_4");
438           }
439         else
440           {
441           extensions->LoadCorePromotedExtension("GL_EXT_blend_func_separate");
442           }
443 
444         if(supports_GL_2_0)
445           {
446           extensions->LoadExtension("GL_VERSION_2_0");
447           }
448         else
449           {
450           extensions->LoadCorePromotedExtension("GL_ARB_vertex_shader");
451           extensions->LoadCorePromotedExtension("GL_ARB_fragment_shader");
452           extensions->LoadCorePromotedExtension("GL_ARB_shader_objects");
453           }
454         if(supports_GL_1_5)
455           {
456           extensions->LoadExtension("GL_VERSION_1_5");
457           }
458         else
459           {
460           extensions->LoadCorePromotedExtension("GL_ARB_occlusion_query");
461           }
462 
463         extensions->LoadExtension("GL_ARB_texture_rectangle");
464 
465         // Some OpenGL implementations such as Mesa or ATI
466         // claim to support both GLSL and GL_ARB_texture_rectangle but
467         // don't actually support sampler2DRectShadow in a GLSL code.
468         // To test that, we compile the shader, if it fails, we don't use
469         // deph peeling
470         GLuint shader =
471           vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
472         vtkgl::ShaderSource(
473           shader, 1,
474           const_cast<const char **>(&vtkOpenGLRenderer_PeelingFS), 0);
475         vtkgl::CompileShader(shader);
476         GLint params;
477         vtkgl::GetShaderiv(shader,vtkgl::COMPILE_STATUS,
478                            &params);
479         this->DepthPeelingIsSupported = params==GL_TRUE;
480         vtkgl::DeleteShader(shader);
481         if(!this->DepthPeelingIsSupported)
482           {
483           vtkDebugMacro("this OpenGL implementation does not support "
484                         "GL_ARB_texture_rectangle in GLSL code");
485           }
486         }
487       else
488         {
489         vtkDebugMacro(<<"depth peeling is not supported.");
490         if(!supports_depth_texture)
491           {
492           vtkDebugMacro(<<"neither OpenGL 1.4 nor GL_ARB_depth_texture is supported");
493           }
494         if(!supports_shadow)
495           {
496           vtkDebugMacro(<<"neither OpenGL 1.4 nor GL_ARB_shadow is supported");
497           }
498         if(!supports_shadow_funcs)
499           {
500           vtkDebugMacro(<<"neither OpenGL 1.5 nor GL_EXT_shadow_funcs is supported");
501           }
502         if(!supports_vertex_shader)
503           {
504           vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_vertex_shader is supported");
505           }
506         if(!supports_fragment_shader)
507           {
508           vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_fragment_shader is supported");
509           }
510         if(!supports_shader_objects)
511           {
512           vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_shader_objects is supported");
513           }
514         if(!supports_occlusion_query)
515           {
516           vtkDebugMacro(<<"neither OpenGL 1.5 nor GL_ARB_occlusion_query is supported");
517           }
518         if(!supports_multitexture)
519           {
520           vtkDebugMacro(<<"neither OpenGL 1.3 nor GL_ARB_multitexture is supported");
521           }
522         if(!supports_GL_ARB_texture_rectangle)
523           {
524           vtkDebugMacro(<<"GL_ARB_texture_rectangle is not supported");
525           }
526         if(!supports_edge_clamp)
527           {
528           vtkDebugMacro(<<"neither OpenGL 1.2 nor GL_SGIS_texture_edge_clamp nor GL_EXT_texture_edge_clamp is not supported");
529           }
530         if(!supportsAtLeast8AlphaBits)
531           {
532           vtkDebugMacro(<<"at least 8 alpha bits is not supported");
533           }
534         if (!driver_support)
535           {
536           vtkDebugMacro(<<"buggy driver (Mesa < 6.5.3 or ATI)");
537           }
538         }
539       }
540     }
541 
542   if(!this->UseDepthPeeling || !this->DepthPeelingIsSupported)
543     {
544     // just alpha blending
545     this->LastRenderingUsedDepthPeeling=0;
546     this->UpdateTranslucentPolygonalGeometry();
547     }
548   else
549     {
550     // depth peeling.
551 
552     // get the viewport dimensions
553     this->GetTiledSizeAndOrigin(&this->ViewportWidth,&this->ViewportHeight,
554                                 &this->ViewportX,&this->ViewportY);
555 
556     // get z bits
557     GLint depthBits;
558     glGetIntegerv(GL_DEPTH_BITS,&depthBits);
559     if(depthBits==16)
560       {
561       this->DepthFormat=vtkgl::DEPTH_COMPONENT16_ARB;
562       }
563     else
564       {
565       this->DepthFormat=vtkgl::DEPTH_COMPONENT24_ARB;
566       }
567 
568     vtkgl::ActiveTexture(vtkgl::TEXTURE1);
569 
570     // check if the GPU supports a viewport sized texture in
571     // the formats we will use. If not then we should fallback
572     // to alpha blending.
573 
574     // This check is really an anachronism since modern GPU
575     // typically support full screen sized textures in all the
576     // common formats.
577 
578     GLint depthTexSupport = 1;
579     GLint colorTexSupport = 1;
580 
581     if ( extensions->DriverIsATI()
582        && !extensions->GetIgnoreDriverBugs("ATI proxy query bug.") )
583       {
584       // The ATI Radeon HD drivers currently choke on the proxy
585       // query, but depth peeling has been confirmed to work. For
586       // those driver fall back on the weaker max texture size
587       // check.
588       GLint maxTexSize = 0;
589       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
590       if ( (this->ViewportWidth > maxTexSize)
591         || (this->ViewportHeight > maxTexSize) )
592         {
593         depthTexSupport = 0;
594         colorTexSupport = 0;
595         }
596       }
597     else
598       {
599       // Not a buggy ATI driver, it's OK to make the proxy query.
600       GLuint proxyQueryTex = 0;
601       glGenTextures(1, &proxyQueryTex);
602       glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB, proxyQueryTex);
603 
604       // support for depth buffer format
605       glTexImage2D(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0, this->DepthFormat,
606                    this->ViewportWidth, this->ViewportHeight, 0,
607                    GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,0);
608 
609       glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0,
610                                GL_TEXTURE_WIDTH, &depthTexSupport);
611 
612       // support for color buffer
613       glTexImage2D(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
614                    this->ViewportWidth, this->ViewportHeight, 0, GL_RGBA,
615                    GL_UNSIGNED_BYTE, 0);
616 
617       glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0,
618                                GL_TEXTURE_WIDTH,&colorTexSupport);
619 
620       glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB, 0);
621       glDeleteTextures(1, &proxyQueryTex);
622       }
623 
624     if (!(depthTexSupport && colorTexSupport))
625       {
626       // GPU does not support a view sized texture in this format.
627       // Do alpha blending technique instead.
628       vtkWarningMacro(
629           << "The GPU supports "
630           << this->ViewportWidth << "x"
631           << this->ViewportHeight << " texture: depth buffer "
632           << (depthTexSupport?"yes":"no") << ", color buffer "
633           << (colorTexSupport?"yes":"no"));
634 
635       vtkgl::ActiveTexture(vtkgl::TEXTURE0);
636       this->LastRenderingUsedDepthPeeling = 0;
637       this->UpdateTranslucentPolygonalGeometry();
638       return;
639       }
640 
641     // 1. Grab the RGBAZ of the opaque layer.
642     GLuint opaqueLayerZ=0;
643     GLuint opaqueLayerRgba=0;
644     glGenTextures(1,&opaqueLayerZ);
645     this->OpaqueLayerZ=opaqueLayerZ;
646 
647     glGenTextures(1,&opaqueLayerRgba);
648     // opaque z format
649     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerZ);
650     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
651                     GL_NEAREST);
652     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
653                     GL_NEAREST);
654     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,
655                     vtkgl::CLAMP_TO_EDGE);
656     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,
657                     vtkgl::CLAMP_TO_EDGE);
658     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
659                     vtkgl::TEXTURE_COMPARE_MODE,
660                     vtkgl::COMPARE_R_TO_TEXTURE);
661     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
662                     vtkgl::TEXTURE_COMPARE_FUNC,
663                     GL_LESS);
664 
665     // Allocate memory
666     glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB,0,this->DepthFormat,
667                  this->ViewportWidth,this->ViewportHeight, 0,
668                  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
669 
670     // Grab the z-buffer
671     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
672                         this->ViewportY,this->ViewportWidth,
673                         this->ViewportHeight);
674 
675     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerRgba);
676     // opaque rgba format
677     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
678                     GL_NEAREST);
679     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
680                     GL_NEAREST);
681 
682     // Allocate memory
683     glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
684                  this->ViewportWidth,this->ViewportHeight, 0, GL_RGBA,
685                  GL_UNSIGNED_BYTE, 0);
686 
687     // Have to be set before a call to UpdateTranslucentPolygonalGeometry()
688     // because UpdateTranslucentPolygonalGeometry() will eventually call
689     // vtkOpenGLActor::Render() that uses this flag.
690     this->LastRenderingUsedDepthPeeling=1;
691 
692     // Grab the rgba-buffer
693     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
694                         this->ViewportY,this->ViewportWidth,
695                         this->ViewportHeight);
696 
697     GLuint queryId;
698     vtkgl::GenQueries(1,&queryId);
699     int stop=0;
700     int infiniteLoop=this->MaximumNumberOfPeels==0;
701 
702     unsigned int threshold=static_cast<unsigned int>(this->ViewportWidth*this->ViewportHeight*OcclusionRatio);
703     this->LayerList=new vtkOpenGLRendererLayerList;
704 
705     // save the default blend function.
706     glPushAttrib(GL_COLOR_BUFFER_BIT);
707 
708     int multiSampleStatus=glIsEnabled(vtkgl::MULTISAMPLE);
709 
710     if(multiSampleStatus)
711       {
712       glDisable(vtkgl::MULTISAMPLE);
713       }
714     glDisable(GL_BLEND);
715     GLuint nbPixels=0;
716     GLuint previousNbPixels=0;
717     int l=0;
718     while(!stop)
719       {
720       vtkgl::BeginQuery(vtkgl::SAMPLES_PASSED,queryId);
721       stop=!this->RenderPeel(l);
722       vtkgl::EndQuery(vtkgl::SAMPLES_PASSED);
723       // blocking call
724       previousNbPixels=nbPixels;
725       if(!stop || l>0) // stop && l==0 <=> no translucent geometry
726         {
727         vtkgl::GetQueryObjectuiv(queryId,vtkgl::QUERY_RESULT,&nbPixels);
728         if(!stop)
729           {
730           stop=(nbPixels<=threshold) || (nbPixels==previousNbPixels);
731           ++l;
732           if(!stop && !infiniteLoop)
733             {
734             stop=l>=this->MaximumNumberOfPeels;
735             }
736           }
737         }
738       }
739     if(multiSampleStatus)
740       {
741       glEnable(vtkgl::MULTISAMPLE);
742       }
743     // The two following lines are taken from vtkOpenGLProperty to
744     // reset texturing state after rendering the props.
745     glDisable(GL_TEXTURE_2D);
746     glDisable (GL_ALPHA_TEST);
747     glDepthFunc(GL_LEQUAL);
748     vtkgl::DeleteQueries(1,&queryId);
749     if(this->TransparentLayerZ!=0)
750       {
751       GLuint transparentLayerZ=static_cast<GLuint>(this->TransparentLayerZ);
752       glDeleteTextures(1,&transparentLayerZ);
753       this->TransparentLayerZ=0;
754       }
755 
756     // Finally, draw sorted opacity
757     glMatrixMode(GL_PROJECTION);
758     glPushMatrix();
759     glLoadIdentity();
760     glOrtho(0, this->ViewportWidth, 0, this->ViewportHeight, -1, 1);
761     glMatrixMode(GL_MODELVIEW);
762     glPushMatrix();
763     glLoadIdentity();
764     glClearColor( static_cast<GLclampf>(0),static_cast<GLclampf>(0),
765                   static_cast<GLclampf>(0),static_cast<GLclampf>(0));
766 
767     glClear(GL_COLOR_BUFFER_BIT);
768     glDisable(GL_DEPTH_TEST);
769 
770     vtkgl::ActiveTexture(vtkgl::TEXTURE0 );
771     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
772     glEnable(vtkgl::TEXTURE_RECTANGLE_ARB);
773 
774     // actor in wireframe may have change that
775     glPolygonMode(GL_FRONT, GL_FILL);
776 
777     glDisable(GL_BLEND);
778     // First the opaque layer
779     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerRgba);
780     glBegin(GL_QUADS);
781     glTexCoord2f(0, 0);
782     glVertex2f(0, 0);
783     glTexCoord2f(this->ViewportWidth, 0);
784     glVertex2f(this->ViewportWidth, 0);
785     glTexCoord2f(this->ViewportWidth, this->ViewportHeight);
786     glVertex2f(this->ViewportWidth, this->ViewportHeight);
787     glTexCoord2f(0, this->ViewportHeight);
788     glVertex2f(0, this->ViewportHeight);
789     glEnd();
790 
791     vtkgl::BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
792                              GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
793     glEnable(GL_BLEND);
794     // the transparent layers
795     std::list<GLuint>::reverse_iterator it=this->LayerList->List.rbegin();
796     std::list<GLuint>::reverse_iterator itEnd=this->LayerList->List.rend();
797     while(it!=itEnd)
798       {
799       glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,(*it));
800 
801       glBegin(GL_QUADS);
802       glTexCoord2f(0, 0);
803       glVertex2f(0, 0);
804       glTexCoord2f(this->ViewportWidth, 0);
805       glVertex2f(this->ViewportWidth, 0);
806       glTexCoord2f(this->ViewportWidth, this->ViewportHeight);
807       glVertex2f(this->ViewportWidth, this->ViewportHeight);
808       glTexCoord2f(0, this->ViewportHeight);
809       glVertex2f(0, this->ViewportHeight);
810       glEnd();
811       ++it;
812       }
813     // Restore the default blend function for the next stage (overlay)
814     glPopAttrib();
815 
816     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
817     glDisable(vtkgl::TEXTURE_RECTANGLE_ARB);
818     glEnable(GL_DEPTH_TEST);
819     glMatrixMode(GL_PROJECTION);
820     glPopMatrix();
821     glMatrixMode(GL_MODELVIEW);
822     glPopMatrix();
823     // Destroy the shader
824     if(this->ProgramShader!=0)
825       {
826       vtkgl::DeleteProgram(this->ProgramShader);
827       this->ProgramShader=0;
828       }
829 
830     // Destroy the layers
831     size_t c=this->LayerList->List.size();
832     GLuint *ids=new GLuint[c];
833     std::list<GLuint>::const_iterator it2=this->LayerList->List.begin();
834     size_t layer=0;
835     while(layer<c)
836       {
837       ids[layer]=(*it2);
838       ++layer;
839       ++it2;
840       }
841     glDeleteTextures(static_cast<GLsizei>(c),ids);
842     delete[] ids;
843     delete this->LayerList;
844     this->LayerList=0;
845 
846     glDeleteTextures(1,&opaqueLayerRgba);
847     glDeleteTextures(1,&opaqueLayerZ);
848     }
849 
850   vtkOpenGLCheckErrorMacro("failed after DeviceRenderTranslucentPolygonalGeometry");
851 }
852 
853 // ----------------------------------------------------------------------------
854 // Description:
855 // Check the compilation status of some fragment shader source.
CheckCompilation(unsigned int fragmentShader)856 void vtkOpenGLRenderer::CheckCompilation(
857   unsigned int fragmentShader)
858 {
859   vtkOpenGLClearErrorMacro();
860   GLuint fs=static_cast<GLuint>(fragmentShader);
861   GLint params;
862   vtkgl::GetShaderiv(fs,vtkgl::COMPILE_STATUS,&params);
863   if(params==GL_TRUE)
864     {
865     vtkDebugMacro(<<"shader source compiled successfully");
866     }
867   else
868     {
869     vtkErrorMacro(<<"shader source compile error");
870     // include null terminator
871     vtkgl::GetShaderiv(fs,vtkgl::INFO_LOG_LENGTH,&params);
872     if(params>0)
873       {
874       char *buffer=new char[params];
875       vtkgl::GetShaderInfoLog(fs,params,0,buffer);
876       vtkErrorMacro(<<"log: "<<buffer);
877       delete[] buffer;
878       }
879     else
880       {
881       vtkErrorMacro(<<"no log");
882       }
883     }
884   vtkOpenGLCheckErrorMacro("failed after CheckCompilation");
885 }
886 
887 // ----------------------------------------------------------------------------
888 // Description:
889 // Render a peel layer. If there is no more GPU RAM to save the texture,
890 // return false otherwise returns true. Also if layer==0 and no prop have
891 // been rendered (there is no translucent geometry), it returns false.
892 // \pre positive_layer: layer>=0
RenderPeel(int layer)893 int vtkOpenGLRenderer::RenderPeel(int layer)
894 {
895   assert("pre: positive_layer" && layer>=0);
896 
897   vtkOpenGLClearErrorMacro();
898 
899   GLbitfield mask=GL_COLOR_BUFFER_BIT;
900   if(layer>0)
901     {
902     mask=mask|GL_DEPTH_BUFFER_BIT;
903     }
904 
905   glClearColor(0.0, 0.0, 0.0, 0.0);
906   glClear(mask);
907 
908   vtkgl::ActiveTexture(vtkgl::TEXTURE2);
909   glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->OpaqueLayerZ);
910   vtkgl::ActiveTexture(vtkgl::TEXTURE1 );
911 
912   if(this->ProgramShader==0)
913     {
914     this->ProgramShader=vtkgl::CreateProgram();
915     GLuint shader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
916     vtkgl::ShaderSource(shader,1,const_cast<const char **>(&vtkOpenGLRenderer_PeelingFS),0);
917     vtkgl::CompileShader(shader);
918     this->CheckCompilation(shader);
919     vtkgl::AttachShader(this->ProgramShader,shader);
920     vtkgl::LinkProgram(this->ProgramShader);
921 
922     GLint params;
923     vtkgl::GetProgramiv(static_cast<GLuint>(this->ProgramShader),vtkgl::LINK_STATUS,&params);
924     if(params==GL_TRUE)
925       {
926       vtkDebugMacro(<<"program linked successfully");
927       }
928     else
929       {
930       vtkErrorMacro(<<"program link error");
931       // include null terminator
932       vtkgl::GetProgramiv(static_cast<GLuint>(this->ProgramShader),vtkgl::INFO_LOG_LENGTH,&params);
933       if(params>0)
934         {
935 #if 1
936         char *buffer=new char[params];
937         vtkgl::GetProgramInfoLog(static_cast<GLuint>(this->ProgramShader),params,0,buffer);
938         vtkErrorMacro(<<"log: "<<buffer);
939         delete[] buffer;
940 #endif
941         }
942       else
943         {
944         vtkErrorMacro(<<"no log: ");
945         }
946       }
947     vtkgl::DeleteShader(shader); // reference counting
948     }
949 
950   if(layer>0)
951     {
952     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
953     vtkgl::UseProgram(this->ProgramShader);
954     GLint uShadowTex=vtkgl::GetUniformLocation(this->ProgramShader,"shadowTex");
955     if(uShadowTex!=-1)
956       {
957       vtkgl::Uniform1i(uShadowTex,1);
958       }
959     else
960       {
961       vtkErrorMacro(<<"error: shadowTex is not a uniform.");
962       }
963     GLint uOpaqueShadowTex=vtkgl::GetUniformLocation(this->ProgramShader,"opaqueShadowTex");
964     if(uOpaqueShadowTex!=-1)
965       {
966       vtkgl::Uniform1i(uOpaqueShadowTex,2);
967       }
968     else
969       {
970       vtkErrorMacro(<<"error: opaqueShadowTex is not a uniform.");
971       }
972 
973     GLint uOffsetX=vtkgl::GetUniformLocation(this->ProgramShader,"offsetX");
974     if(uOffsetX!=-1)
975       {
976       vtkgl::Uniform1f(uOffsetX,this->ViewportX);
977       }
978     else
979       {
980       vtkErrorMacro(<<"error: offsetX is not a uniform.");
981       }
982 
983     GLint uOffsetY=vtkgl::GetUniformLocation(this->ProgramShader,"offsetY");
984     if(uOffsetY!=-1)
985       {
986       vtkgl::Uniform1f(uOffsetY,this->ViewportY);
987       }
988     else
989       {
990       vtkErrorMacro(<<"error: offsetY is not a uniform.");
991       }
992     }
993   vtkgl::ActiveTexture(vtkgl::TEXTURE0 );
994   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
995   this->DepthPeelingHigherLayer=layer>0;
996   int numberOfRenderedProps=this->UpdateTranslucentPolygonalGeometry();
997   if(layer>0)
998     {
999     this->DepthPeelingHigherLayer=0;
1000     vtkgl::UseProgram(0);
1001     }
1002 
1003   vtkgl::ActiveTexture(vtkgl::TEXTURE1 );
1004   if(layer==0)
1005     {
1006     if(numberOfRenderedProps>0)
1007       {
1008       GLuint transparentLayerZ;
1009       glGenTextures(1,&transparentLayerZ);
1010       this->TransparentLayerZ=static_cast<unsigned int>(transparentLayerZ);
1011       glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
1012 
1013       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
1014                       GL_NEAREST);
1015       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
1016                       GL_NEAREST);
1017       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,
1018                       vtkgl::CLAMP_TO_EDGE);
1019       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,
1020                       vtkgl::CLAMP_TO_EDGE);
1021       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
1022                       vtkgl::TEXTURE_COMPARE_MODE,
1023                       vtkgl::COMPARE_R_TO_TEXTURE);
1024       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
1025                       vtkgl::TEXTURE_COMPARE_FUNC,
1026                       GL_GREATER);
1027 
1028       // Allocate memory, note: verified GPU support for this
1029       // texture format above.
1030       glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB,0,this->DepthFormat,
1031                    this->ViewportWidth,this->ViewportHeight, 0,
1032                    GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
1033       }
1034     }
1035   else
1036     {
1037     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
1038     }
1039   if((layer==0 && numberOfRenderedProps>0) || layer>0)
1040     {
1041     // Grab the z-buffer
1042     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
1043                         this->ViewportY,this->ViewportWidth,
1044                         this->ViewportHeight);
1045 
1046     // Grab the rgba buffer
1047     GLuint rgba;
1048     glGenTextures(1,&rgba);
1049     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,rgba);
1050     // rgba format
1051     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
1052                     GL_NEAREST);
1053     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
1054                     GL_NEAREST);
1055 
1056     // Allocate memory, note: verified GPU support for this
1057     // texture format above.
1058     glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
1059                  this->ViewportWidth,this->ViewportHeight, 0, GL_RGBA,
1060                  GL_UNSIGNED_BYTE, 0);
1061 
1062     // Grab the rgba-buffer
1063     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
1064                         this->ViewportY,this->ViewportWidth,
1065                         this->ViewportHeight);
1066     this->LayerList->List.push_back(rgba);
1067 
1068     vtkOpenGLCheckErrorMacro("failed after RenderPeel");
1069     return 1;
1070     }
1071   else
1072     {
1073     vtkOpenGLCheckErrorMacro("failed after RenderPeel");
1074     return 0;
1075     }
1076 }
1077 
1078 // ----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1079 void vtkOpenGLRenderer::PrintSelf(ostream& os, vtkIndent indent)
1080 {
1081   this->Superclass::PrintSelf(os,indent);
1082 
1083   os << indent << "Number Of Lights Bound: " <<
1084     this->NumberOfLightsBound << "\n";
1085   os << indent << "PickBuffer " << this->PickInfo->PickBuffer << "\n";
1086   os << indent << "PickedId" << this->PickInfo->PickedId<< "\n";
1087   os << indent << "NumPicked" << this->PickInfo->NumPicked<< "\n";
1088   os << indent << "PickedZ " << this->PickedZ << "\n";
1089   os << indent << "Pass:";
1090   if(this->Pass!=0)
1091     {
1092       os << "exists" << endl;
1093     }
1094   else
1095     {
1096       os << "null" << endl;
1097     }
1098 }
1099 
1100 
Clear(void)1101 void vtkOpenGLRenderer::Clear(void)
1102 {
1103   vtkOpenGLClearErrorMacro();
1104 
1105   GLbitfield  clear_mask = 0;
1106 
1107   if (! this->Transparent())
1108     {
1109     glClearColor( static_cast<GLclampf>(this->Background[0]),
1110                   static_cast<GLclampf>(this->Background[1]),
1111                   static_cast<GLclampf>(this->Background[2]),
1112                   static_cast<GLclampf>(0.0));
1113     clear_mask |= GL_COLOR_BUFFER_BIT;
1114     }
1115 
1116   if (!this->GetPreserveDepthBuffer())
1117     {
1118     glClearDepth(static_cast<GLclampf>(1.0));
1119     clear_mask |= GL_DEPTH_BUFFER_BIT;
1120     }
1121 
1122   vtkDebugMacro(<< "glClear\n");
1123   glClear(clear_mask);
1124 
1125   // If gradient background is turned on, draw it now.
1126   if (!this->Transparent() &&
1127       (this->GradientBackground || this->TexturedBackground))
1128     {
1129     double tile_viewport[4];
1130     this->GetRenderWindow()->GetTileViewport(tile_viewport);
1131     glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT);
1132     glDisable(GL_ALPHA_TEST);
1133     glDisable(GL_DEPTH_TEST);
1134     glDisable(GL_LIGHTING);
1135     glDisable(GL_TEXTURE_1D);
1136     glDisable(GL_TEXTURE_2D);
1137     glDisable(GL_BLEND);
1138     glShadeModel(GL_SMOOTH); // color interpolation
1139 
1140     glMatrixMode(GL_MODELVIEW);
1141     glPushMatrix();
1142     {
1143       glLoadIdentity();
1144       glMatrixMode(GL_PROJECTION);
1145       glPushMatrix();
1146       {
1147         glLoadIdentity();
1148         glOrtho(
1149           tile_viewport[0],
1150           tile_viewport[2],
1151           tile_viewport[1],
1152           tile_viewport[3],
1153           -1.0, 1.0);
1154 
1155         //top vertices
1156         if(this->TexturedBackground && this->BackgroundTexture)
1157           {
1158           glEnable(GL_TEXTURE_2D);
1159 
1160           this->BackgroundTexture->Render(this);
1161 
1162           // NOTE: By default the mode is GL_MODULATE. Since the user
1163           // cannot set the mode, the default is set to replace.
1164           glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1165           glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1166           glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1167 
1168           // NOTE: vtkTexture Render enables the alpha test
1169           // so that no buffer is affected if alpha of incoming fragment is
1170           // below the threshold. Here we have to enable it so that it won't
1171           // rejects the fragments of the quad as the alpha is set to 0 on it.
1172           glDisable(GL_ALPHA_TEST);
1173           }
1174 
1175         glBegin(GL_QUADS);
1176         glColor4d(this->Background[0],this->Background[1],this->Background[2],
1177                   0.0);
1178         glTexCoord2f(0.0, 0.0);
1179         glVertex2f(0.0, 0.0);
1180 
1181         glTexCoord2f(1.0, 0.0);
1182         glVertex2f(1.0, 0);
1183 
1184         //bottom vertices
1185         glColor4d(this->Background2[0],this->Background2[1],
1186                   this->Background2[2],0.0);
1187         glTexCoord2f(1.0, 1.0);
1188         glVertex2f(1.0, 1.0);
1189 
1190         glTexCoord2f(0.0, 1.0);
1191         glVertex2f(0.0, 1.0);
1192 
1193         glEnd();
1194       }
1195       glMatrixMode(GL_PROJECTION);
1196       glPopMatrix();
1197     }
1198     glMatrixMode(GL_MODELVIEW);
1199     glPopMatrix();
1200     glPopAttrib();
1201     }
1202   vtkOpenGLCheckErrorMacro("failed after Clear");
1203 }
1204 
StartPick(unsigned int pickFromSize)1205 void vtkOpenGLRenderer::StartPick(unsigned int pickFromSize)
1206 {
1207   vtkOpenGLClearErrorMacro();
1208 
1209   int bufferSize = pickFromSize * 4;
1210 
1211   // Do not remove this MakeCurrent! Due to Start / End methods on
1212   // some objects which get executed during a pipeline update,
1213   // other windows might get rendered since the last time
1214   // a MakeCurrent was called.
1215   this->RenderWindow->MakeCurrent();
1216   this->RenderWindow->IsPickingOn();
1217   if (this->PickInfo->PickBuffer)
1218     {
1219     delete [] this->PickInfo->PickBuffer;
1220     this->PickInfo->PickBuffer = 0;
1221     }
1222   this->PickInfo->PickBuffer = new GLuint[bufferSize];
1223   glSelectBuffer(bufferSize, this->PickInfo->PickBuffer);
1224   // change to selection mode
1225   (void)glRenderMode(GL_SELECT);
1226   // initialize the pick names and add a 0 name, for no pick
1227   glInitNames();
1228   glPushName(0);
1229 
1230   vtkOpenGLCheckErrorMacro("failed after StartPick");
1231 }
1232 
ReleaseGraphicsResources(vtkWindow * w)1233 void vtkOpenGLRenderer::ReleaseGraphicsResources(vtkWindow *w)
1234 {
1235   if (w && this->Pass)
1236     {
1237     this->Pass->ReleaseGraphicsResources(w);
1238     }
1239 }
1240 
UpdatePickId()1241 void vtkOpenGLRenderer::UpdatePickId()
1242 {
1243   glLoadName(this->CurrentPickId++);
1244   vtkOpenGLCheckErrorMacro("failed after UpdatePick");
1245 }
1246 
1247 
DevicePickRender()1248 void vtkOpenGLRenderer::DevicePickRender()
1249 {
1250   // Do not remove this MakeCurrent! Due to Start / End methods on
1251   // some objects which get executed during a pipeline update,
1252   // other windows might get rendered since the last time
1253   // a MakeCurrent was called.
1254   this->RenderWindow->MakeCurrent();
1255   vtkOpenGLClearErrorMacro();
1256 
1257   // standard render method
1258   this->ClearLights();
1259 
1260   this->UpdateCamera();
1261   this->UpdateLightGeometry();
1262   this->UpdateLights();
1263 
1264   // set matrix mode for actors
1265   glMatrixMode(GL_MODELVIEW);
1266 
1267   this->PickGeometry();
1268 
1269   // clean up the model view matrix set up by the camera
1270   glMatrixMode(GL_MODELVIEW);
1271   glPopMatrix();
1272   vtkOpenGLCheckErrorMacro("failed after DevicePickRender");
1273 }
1274 
1275 
DonePick()1276 void vtkOpenGLRenderer::DonePick()
1277 {
1278   glFlush();
1279   GLuint hits = glRenderMode(GL_RENDER);
1280   this->PickInfo->NumPicked = hits;
1281 
1282   unsigned int depth = static_cast<unsigned int>(-1);
1283   GLuint* ptr = this->PickInfo->PickBuffer;
1284   this->PickInfo->PickedId = 0;
1285   for(unsigned int k =0; k < hits; k++)
1286     {
1287     int num_names = *ptr;
1288     int save = 0;
1289     ptr++; // move to first depth value
1290     if(*ptr <= depth)
1291       {
1292       depth = *ptr;
1293       save = 1;
1294       }
1295     ptr++; // move to next depth value
1296     if(*ptr <= depth)
1297       {
1298       depth = *ptr;
1299       save = 1;
1300       }
1301     // move to first name picked
1302     ptr++;
1303     if(save)
1304       {
1305       this->PickInfo->PickedId = *ptr;
1306       }
1307     // skip additional names
1308     ptr += num_names;
1309     }
1310   // If there was a pick, then get the Z value
1311   if(this->PickInfo->PickedId)
1312     {
1313     // convert from pick depth described as:
1314     // Returned depth values are mapped such that the largest unsigned
1315     // integer value corresponds to window coordinate depth 1.0,
1316     // and zero corresponds to window coordinate depth 0.0.
1317 
1318     this->PickedZ = depth/static_cast<double>(VTK_UNSIGNED_INT_MAX);
1319 
1320     // Clamp to range [0,1]
1321     this->PickedZ = (this->PickedZ < 0.0) ? 0.0 : this->PickedZ;
1322     this->PickedZ = (this->PickedZ > 1.0) ? 1.0: this->PickedZ;
1323     }
1324 
1325   //Don't delete the list, keep it around in case caller wants all
1326   //of the hits. Delete it elsewhere when needed.
1327   //delete [] this->PickInfo->PickBuffer;
1328   //this->PickInfo->PickBuffer = 0;
1329 
1330   this->RenderWindow->IsPickingOff();
1331 }
1332 
GetPickedZ()1333 double vtkOpenGLRenderer::GetPickedZ()
1334 {
1335   return this->PickedZ;
1336 }
1337 
GetPickedId()1338 unsigned int vtkOpenGLRenderer::GetPickedId()
1339 {
1340   return static_cast<unsigned int>(this->PickInfo->PickedId);
1341 }
1342 
~vtkOpenGLRenderer()1343 vtkOpenGLRenderer::~vtkOpenGLRenderer()
1344 {
1345   if (this->PickInfo->PickBuffer)
1346     {
1347     delete [] this->PickInfo->PickBuffer;
1348     this->PickInfo->PickBuffer = 0;
1349     }
1350   delete this->PickInfo;
1351 
1352   if(this->ShaderProgram!=0)
1353     {
1354     this->ShaderProgram->Delete();
1355     }
1356 
1357   if(this->Pass!=0)
1358     {
1359     this->Pass->UnRegister(this);
1360     }
1361 }
1362 
GetNumPickedIds()1363 unsigned int vtkOpenGLRenderer::GetNumPickedIds()
1364 {
1365   return static_cast<unsigned int>(this->PickInfo->NumPicked);
1366 }
1367 
GetPickedIds(unsigned int atMost,unsigned int * callerBuffer)1368 int vtkOpenGLRenderer::GetPickedIds(unsigned int atMost,
1369                                     unsigned int *callerBuffer)
1370 {
1371   if (!this->PickInfo->PickBuffer)
1372     {
1373     return 0;
1374     }
1375 
1376   unsigned int max = (atMost < this->PickInfo->NumPicked) ? atMost : this->PickInfo->NumPicked;
1377   GLuint* iptr = this->PickInfo->PickBuffer;
1378   unsigned int *optr = callerBuffer;
1379   unsigned int k;
1380   for(k =0; k < max; k++)
1381     {
1382     int num_names = *iptr;
1383     iptr++; // move to first depth value
1384     iptr++; // move to next depth value
1385     iptr++; // move to first name picked
1386     *optr = static_cast<unsigned int>(*iptr);
1387     optr++;
1388     // skip additional names
1389     iptr += num_names;
1390     }
1391   return k;
1392 }
1393