1 /*=========================================================================
2 
3 Program:   Visualization Toolkit
4 Module:    vtkDepthPeelingPass.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 
16 #include "vtkDepthPeelingPass.h"
17 #include "vtkObjectFactory.h"
18 #include <cassert>
19 #include "vtkRenderState.h"
20 #include "vtkProp.h"
21 #include "vtkRenderer.h"
22 #include "vtkOpenGLRenderer.h"
23 #include "vtkOpenGLRenderWindow.h"
24 #include "vtkOpenGLExtensionManager.h"
25 #include "vtkgl.h"
26 #include <list>
27 #include "vtkShaderProgram2.h"
28 #include "vtkShader2.h"
29 #include "vtkShader2Collection.h"
30 #include "vtkUniformVariables.h"
31 #include "vtkTextureUnitManager.h"
32 #include "vtkOpenGLError.h"
33 
34 vtkStandardNewMacro(vtkDepthPeelingPass);
35 vtkCxxSetObjectMacro(vtkDepthPeelingPass,TranslucentPass,vtkRenderPass);
36 
37 // List of rgba layers, id are 2D rectangle texture Ids.
38 class vtkDepthPeelingPassLayerList
39 {
40 public:
41   std::list<GLuint> List;
42 };
43 
44 extern const char *vtkDepthPeeling_fs;
45 
46 // ----------------------------------------------------------------------------
vtkDepthPeelingPass()47 vtkDepthPeelingPass::vtkDepthPeelingPass()
48 {
49   this->TranslucentPass=0;
50   this->IsSupported=false;
51   this->IsChecked=false;
52 
53   this->OcclusionRatio=0.0;
54   this->MaximumNumberOfPeels=4;
55   this->LastRenderingUsedDepthPeeling=false;
56   this->DepthPeelingHigherLayer=0;
57   this->Prog=vtkShaderProgram2::New();
58   this->Shader=vtkShader2::New();
59   this->Prog->GetShaders()->AddItem(this->Shader);
60   this->Shader->SetSourceCode(vtkDepthPeeling_fs);
61   this->Shader->SetType(VTK_SHADER_TYPE_FRAGMENT);
62 
63   vtkUniformVariables *v=this->Shader->GetUniformVariables();
64 
65   this->ShadowTexUnit=-1; // not allocated
66   this->OpaqueShadowTexUnit=-1; // not allocated
67 
68 
69   int value;
70   value=1;
71   v->SetUniformi("shadowTex",1,&value);
72   value=2;
73   v->SetUniformi("opaqueShadowTex",1,&value);
74 }
75 
76 // ----------------------------------------------------------------------------
~vtkDepthPeelingPass()77 vtkDepthPeelingPass::~vtkDepthPeelingPass()
78 {
79   if(this->TranslucentPass!=0)
80     {
81       this->TranslucentPass->Delete();
82     }
83   this->Shader->Delete();
84   this->Prog->Delete();
85 }
86 
87 //-----------------------------------------------------------------------------
88 // Description:
89 // Destructor. Delete SourceCode if any.
ReleaseGraphicsResources(vtkWindow * w)90 void vtkDepthPeelingPass::ReleaseGraphicsResources(vtkWindow *w)
91 {
92   assert("pre: w_exists" && w!=0);
93   this->Shader->ReleaseGraphicsResources();
94   this->Prog->ReleaseGraphicsResources();
95   if(this->TranslucentPass)
96     {
97     this->TranslucentPass->ReleaseGraphicsResources(w);
98     }
99 }
100 
101 // ----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)102 void vtkDepthPeelingPass::PrintSelf(ostream& os, vtkIndent indent)
103 {
104   this->Superclass::PrintSelf(os,indent);
105 
106   os << indent << "OcclusionRation: " << this->OcclusionRatio << endl;
107 
108   os << indent << "MaximumNumberOfPeels: " << this->MaximumNumberOfPeels
109      << endl;
110 
111   os << indent << "LastRenderingUsedDepthPeeling: ";
112   if(this->LastRenderingUsedDepthPeeling)
113     {
114     os << "On" << endl;
115     }
116   else
117     {
118     os << "Off" << endl;
119     }
120 
121   os << indent << "TranslucentPass:";
122   if(this->TranslucentPass!=0)
123     {
124     this->TranslucentPass->PrintSelf(os,indent);
125     }
126   else
127     {
128     os << "(none)" <<endl;
129     }
130 }
131 
132 // ----------------------------------------------------------------------------
133 // Description:
134 // Perform rendering according to a render state \p s.
135 // \pre s_exists: s!=0
Render(const vtkRenderState * s)136 void vtkDepthPeelingPass::Render(const vtkRenderState *s)
137 {
138   assert("pre: s_exists" && s!=0);
139 
140   this->NumberOfRenderedProps=0;
141 
142   if(this->TranslucentPass==0)
143     {
144       vtkWarningMacro(<<"No TranslucentPass delegate set. Nothing can be rendered.");
145       return;
146     }
147 
148   // Any prop to render?
149   bool hasTranslucentPolygonalGeometry=false;
150   int i=0;
151   while(!hasTranslucentPolygonalGeometry && i<s->GetPropArrayCount())
152     {
153       hasTranslucentPolygonalGeometry=
154         s->GetPropArray()[i]->HasTranslucentPolygonalGeometry()==1;
155       ++i;
156     }
157   if(!hasTranslucentPolygonalGeometry)
158     {
159       return; // nothing to render.
160     }
161 
162   // check driver support
163   vtkOpenGLRenderWindow *context
164     = vtkOpenGLRenderWindow::SafeDownCast(s->GetRenderer()->GetRenderWindow());
165 
166   this->CheckSupport(context);
167 
168   vtkOpenGLExtensionManager *extensions = context->GetExtensionManager();
169 
170   if(!this->IsSupported)
171     {
172       // just alpha blending
173       this->LastRenderingUsedDepthPeeling=false;
174       this->TranslucentPass->Render(s);
175       this->NumberOfRenderedProps=this->TranslucentPass->GetNumberOfRenderedProps();
176       return;
177     }
178 
179   vtkOpenGLClearErrorMacro();
180 
181   // Depth peeling.
182   vtkRenderer *r=s->GetRenderer();
183 
184   if(s->GetFrameBuffer()==0)
185     {
186     // get the viewport dimensions
187     r->GetTiledSizeAndOrigin(&this->ViewportWidth,&this->ViewportHeight,
188                              &this->ViewportX,&this->ViewportY);
189     }
190   else
191     {
192     int size[2];
193     s->GetWindowSize(size);
194     this->ViewportWidth=size[0];
195     this->ViewportHeight=size[1];
196     this->ViewportX=0;
197     this->ViewportY=0;
198     }
199 
200   // get z bits
201   GLint depthBits;
202   glGetIntegerv(GL_DEPTH_BITS,&depthBits);
203   if(depthBits==16)
204     {
205       this->DepthFormat=vtkgl::DEPTH_COMPONENT16_ARB;
206     }
207   else
208     {
209       this->DepthFormat=vtkgl::DEPTH_COMPONENT24_ARB;
210     }
211 
212   // NOTE, this class expects texture unit already selected
213   // don't change it.
214   //vtkgl::ActiveTexture(vtkgl::TEXTURE1);
215 
216   // check if the GPU supports a viewport sized texture in
217   // the formats we will use. If not then we should fallback
218   // to alpha blending.
219 
220   // This check is really an anachronism since modern GPU
221   // typically support full screen sized textures in all the
222   // common formats.
223 
224   GLint depthTexSupport = 1;
225   GLint colorTexSupport = 1;
226 
227   if ( extensions->DriverIsATI()
228      && !extensions->GetIgnoreDriverBugs("ATI proxy query bug.") )
229     {
230     // The ATI Radeon HD drivers currently choke on the proxy
231     // query, but depth peeling has been confirmed to work. For
232     // those driver fall back on the weaker max texture size
233     // check.
234     GLint maxTexSize = 0;
235     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
236     if ( (this->ViewportWidth > maxTexSize)
237       || (this->ViewportHeight > maxTexSize) )
238       {
239       depthTexSupport = 0;
240       colorTexSupport = 0;
241       }
242     }
243   else
244     {
245     // Not a buggy ATI driver, it's OK to make the proxy query.
246     GLuint proxyQueryTex = 0;
247     glGenTextures(1, &proxyQueryTex);
248     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB, proxyQueryTex);
249 
250     // support for depth buffer format
251     glTexImage2D(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0, this->DepthFormat,
252                  this->ViewportWidth, this->ViewportHeight, 0,
253                  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,0);
254 
255     glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0,
256                              GL_TEXTURE_WIDTH, &depthTexSupport);
257 
258     // support for color buffer
259     glTexImage2D(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
260                  this->ViewportWidth, this->ViewportHeight, 0, GL_RGBA,
261                  GL_UNSIGNED_BYTE, 0);
262 
263     glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0,
264                              GL_TEXTURE_WIDTH,&colorTexSupport);
265 
266     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB, 0);
267     glDeleteTextures(1, &proxyQueryTex);
268     }
269 
270   if (!(depthTexSupport && colorTexSupport))
271     {
272     // GPU does not support a view sized texture in this format.
273     // Do alpha blending technique instead.
274     vtkWarningMacro(
275         << "The GPU supports "
276         << this->ViewportWidth << "x"
277         << this->ViewportHeight << " texture: depth buffer "
278         << (depthTexSupport?"yes":"no") << ", color buffer "
279         << (colorTexSupport?"yes":"no"));
280 
281     this->LastRenderingUsedDepthPeeling = false;
282     vtkgl::ActiveTexture(vtkgl::TEXTURE0);
283     this->TranslucentPass->Render(s);
284     this->NumberOfRenderedProps
285       = this->TranslucentPass->GetNumberOfRenderedProps();
286     return;
287     }
288 
289   // Have to be set before a call to UpdateTranslucentPolygonalGeometry()
290   // because UpdateTranslucentPolygonalGeometry() will eventually call
291   // vtkOpenGLActor::Render() that uses this flag.
292   this->LastRenderingUsedDepthPeeling = true;
293   this->SetLastRenderingUsedDepthPeeling(s->GetRenderer(), true);
294 
295     // 1. Grab the RGBAZ of the opaque layer.
296     GLuint opaqueLayerZ=0;
297     GLuint opaqueLayerRgba=0;
298     glGenTextures(1,&opaqueLayerZ);
299     this->OpaqueLayerZ=opaqueLayerZ;
300 
301     glGenTextures(1,&opaqueLayerRgba);
302     // opaque z format
303 //    vtkgl::ActiveTexture(vtkgl::TEXTURE1 );
304     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerZ);
305     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
306                     GL_NEAREST);
307     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
308                     GL_NEAREST);
309     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,
310                     vtkgl::CLAMP_TO_EDGE);
311     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,
312                     vtkgl::CLAMP_TO_EDGE);
313     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
314                     vtkgl::TEXTURE_COMPARE_MODE,
315                     vtkgl::COMPARE_R_TO_TEXTURE);
316     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
317                     vtkgl::TEXTURE_COMPARE_FUNC,
318                     GL_LESS);
319 
320     // Allocate memory
321     glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB,0,this->DepthFormat,
322                  this->ViewportWidth,this->ViewportHeight, 0,
323                  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
324     // Grab the z-buffer
325     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
326                         this->ViewportY,this->ViewportWidth,
327                         this->ViewportHeight);
328     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerRgba);
329     // opaque rgba format
330     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
331                     GL_NEAREST);
332     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
333                     GL_NEAREST);
334     // Allocate memory
335     glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
336                  this->ViewportWidth,this->ViewportHeight, 0, GL_RGBA,
337                  GL_UNSIGNED_BYTE, 0);
338 
339     // Grab the rgba-buffer
340     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
341                         this->ViewportY,this->ViewportWidth,
342                         this->ViewportHeight);
343 
344     GLuint queryId;
345     vtkgl::GenQueries(1,&queryId);
346     int stop=0;
347     int infiniteLoop=this->MaximumNumberOfPeels==0;
348 
349     unsigned int threshold=static_cast<unsigned int>(this->ViewportWidth*this->ViewportHeight*OcclusionRatio);
350     this->LayerList=new vtkDepthPeelingPassLayerList;
351 
352     // save the default blend function.
353     glPushAttrib(GL_COLOR_BUFFER_BIT);
354 
355     int multiSampleStatus=glIsEnabled(vtkgl::MULTISAMPLE);
356 
357     if(multiSampleStatus)
358       {
359       glDisable(vtkgl::MULTISAMPLE);
360       }
361     glDisable(GL_BLEND);
362 
363     vtkUniformVariables *v=this->Shader->GetUniformVariables();
364     float value;
365     value=this->ViewportX;
366     v->SetUniformf("offsetX",1,&value);
367     value=this->ViewportY;
368     v->SetUniformf("offsetY",1,&value);
369 
370 
371     this->Prog->SetContext(static_cast<vtkOpenGLRenderWindow *>(
372                              s->GetRenderer()->GetRenderWindow()));
373     this->Shader->SetContext(this->Prog->GetContext());
374 
375     GLuint nbPixels=0;
376     GLuint previousNbPixels=0;
377     int l=0;
378     while(!stop)
379       {
380       vtkgl::BeginQuery(vtkgl::SAMPLES_PASSED,queryId);
381       stop=!this->RenderPeel(s,l);
382       vtkgl::EndQuery(vtkgl::SAMPLES_PASSED);
383       // blocking call
384       previousNbPixels=nbPixels;
385       if(!stop || l>0) // stop && l==0 <=> no translucent geometry
386         {
387         vtkgl::GetQueryObjectuiv(queryId,vtkgl::QUERY_RESULT,&nbPixels);
388         ++l;
389         if(!stop)
390           {
391           stop=(nbPixels<=threshold) || (nbPixels==previousNbPixels);
392           if(!stop && !infiniteLoop)
393             {
394             stop=l>=this->MaximumNumberOfPeels;
395             }
396           }
397         }
398       }
399 
400     if(l>1) // some higher layer, we allocated some tex unit in RenderPeel()
401       {
402       vtkTextureUnitManager *m=context->GetTextureUnitManager();
403       m->Free(this->ShadowTexUnit);
404       m->Free(this->OpaqueShadowTexUnit);
405       this->ShadowTexUnit=-1;
406       this->OpaqueShadowTexUnit=-1;
407       }
408 
409     if(multiSampleStatus)
410       {
411       glEnable(vtkgl::MULTISAMPLE);
412       }
413     // The two following lines are taken from vtkOpenGLProperty to
414     // reset texturing state after rendering the props.
415     glDisable(GL_TEXTURE_2D);
416     glDisable (GL_ALPHA_TEST);
417     glDepthFunc(GL_LEQUAL);
418     vtkgl::DeleteQueries(1,&queryId);
419     if(this->TransparentLayerZ!=0)
420       {
421       GLuint transparentLayerZ=static_cast<GLuint>(this->TransparentLayerZ);
422       glDeleteTextures(1,&transparentLayerZ);
423       this->TransparentLayerZ=0;
424       }
425 
426     // Finally, draw sorted opacity
427     glMatrixMode(GL_PROJECTION);
428     glPushMatrix();
429     glLoadIdentity();
430     glOrtho(0, this->ViewportWidth, 0, this->ViewportHeight, -1, 1);
431     glMatrixMode(GL_MODELVIEW);
432     glPushMatrix();
433     glLoadIdentity();
434     glClearColor( static_cast<GLclampf>(0),static_cast<GLclampf>(0),
435                   static_cast<GLclampf>(0),static_cast<GLclampf>(0));
436 
437     glClear(GL_COLOR_BUFFER_BIT);
438     glDisable(GL_DEPTH_TEST);
439 
440     vtkgl::ActiveTexture(vtkgl::TEXTURE0 );
441     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
442     glEnable(vtkgl::TEXTURE_RECTANGLE_ARB);
443 
444     // actor in wireframe may have change that
445     glPolygonMode(GL_FRONT, GL_FILL);
446 
447     glDisable(GL_BLEND);
448     // First the opaque layer
449     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerRgba);
450     glBegin(GL_QUADS);
451     glTexCoord2f(0, 0);
452     glVertex2f(0, 0);
453     glTexCoord2f(this->ViewportWidth, 0);
454     glVertex2f(this->ViewportWidth, 0);
455     glTexCoord2f(this->ViewportWidth, this->ViewportHeight);
456     glVertex2f(this->ViewportWidth, this->ViewportHeight);
457     glTexCoord2f(0, this->ViewportHeight);
458     glVertex2f(0, this->ViewportHeight);
459     glEnd();
460 
461     vtkgl::BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
462                              GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
463     glEnable(GL_BLEND);
464     // the transparent layers
465     std::list<GLuint>::reverse_iterator it=this->LayerList->List.rbegin();
466     std::list<GLuint>::reverse_iterator itEnd=this->LayerList->List.rend();
467     while(it!=itEnd)
468       {
469       glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,(*it));
470 
471       glBegin(GL_QUADS);
472       glTexCoord2f(0, 0);
473       glVertex2f(0, 0);
474       glTexCoord2f(this->ViewportWidth, 0);
475       glVertex2f(this->ViewportWidth, 0);
476       glTexCoord2f(this->ViewportWidth, this->ViewportHeight);
477       glVertex2f(this->ViewportWidth, this->ViewportHeight);
478       glTexCoord2f(0, this->ViewportHeight);
479       glVertex2f(0, this->ViewportHeight);
480       glEnd();
481       ++it;
482       }
483     // Restore the default blend function for the next stage (overlay)
484     glPopAttrib();
485 
486     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
487     glDisable(vtkgl::TEXTURE_RECTANGLE_ARB);
488     glEnable(GL_DEPTH_TEST);
489     glMatrixMode(GL_PROJECTION);
490     glPopMatrix();
491     glMatrixMode(GL_MODELVIEW);
492     glPopMatrix();
493 
494     // Destroy the layers
495     size_t c=this->LayerList->List.size();
496     GLuint *ids=new GLuint[c];
497     std::list<GLuint>::const_iterator it2=this->LayerList->List.begin();
498     size_t layer=0;
499     while(layer<c)
500       {
501       ids[layer]=(*it2);
502       ++layer;
503       ++it2;
504       }
505     glDeleteTextures(static_cast<GLsizei>(c),ids);
506     delete[] ids;
507     delete this->LayerList;
508     this->LayerList=0;
509 
510     glDeleteTextures(1,&opaqueLayerRgba);
511     glDeleteTextures(1,&opaqueLayerZ);
512     this->NumberOfRenderedProps=this->TranslucentPass->GetNumberOfRenderedProps();
513 
514     vtkOpenGLCheckErrorMacro("failed after Render");
515 }
516 
517 // ----------------------------------------------------------------------------
CheckSupport(vtkOpenGLRenderWindow * w)518 void vtkDepthPeelingPass::CheckSupport(vtkOpenGLRenderWindow *w)
519 {
520   assert("pre: w_exists" && w!=0);
521   vtkOpenGLClearErrorMacro();
522 
523   vtkOpenGLExtensionManager *extensions=w->GetExtensionManager();
524 
525   if(!this->IsChecked || w->GetContextCreationTime()>this->CheckTime)
526     {
527       this->IsChecked=true;
528       this->CheckTime.Modified();
529 
530       bool supports_GL_1_3=extensions->ExtensionSupported("GL_VERSION_1_3")==1;
531       bool supports_GL_1_4=extensions->ExtensionSupported("GL_VERSION_1_4")==1;
532       bool supports_GL_1_5=extensions->ExtensionSupported("GL_VERSION_1_5")==1;
533       bool supports_GL_2_0=extensions->ExtensionSupported("GL_VERSION_2_0")==1;
534 
535       bool supports_vertex_shader;
536       bool supports_fragment_shader;
537       bool supports_shader_objects;
538       if(supports_GL_2_0)
539         {
540         supports_vertex_shader=true;
541         supports_fragment_shader=true;
542         supports_shader_objects=true;
543         }
544       else
545         {
546         supports_vertex_shader=extensions->ExtensionSupported("GL_ARB_vertex_shader")==1;
547         supports_fragment_shader=extensions->ExtensionSupported("GL_ARB_fragment_shader")==1;
548         supports_shader_objects=extensions->ExtensionSupported("GL_ARB_shader_objects")==1;
549         }
550       bool supports_multitexture=supports_GL_1_3 || extensions->ExtensionSupported("GL_ARB_multitexture");
551       bool supports_occlusion_query;
552       bool supports_shadow_funcs;
553       if(supports_GL_1_5)
554         {
555         supports_occlusion_query=true;
556         supports_shadow_funcs=true;
557         }
558       else
559         {
560         supports_occlusion_query=extensions->ExtensionSupported("GL_ARB_occlusion_query")==1;
561         supports_shadow_funcs=extensions->ExtensionSupported("GL_EXT_shadow_funcs")==1;
562         }
563 
564       bool supports_depth_texture;
565       bool supports_shadow;
566       bool supports_blend_func_separate;
567       if(supports_GL_1_4)
568         {
569         supports_depth_texture=true;
570         supports_blend_func_separate=true;
571         supports_shadow=true;
572         }
573       else
574         {
575         supports_depth_texture=extensions->ExtensionSupported("GL_ARB_depth_texture")==1;
576         supports_shadow=extensions->ExtensionSupported("GL_ARB_shadow")==1;
577         supports_blend_func_separate=extensions->ExtensionSupported("GL_EXT_blend_func_separate")==1;
578         }
579 
580       bool supports_GL_ARB_texture_rectangle=extensions->ExtensionSupported("GL_ARB_texture_rectangle")==1;
581 
582       // spec claims it is GL_SGIS_texture_edge_clamp, reality shows it is
583       // GL_EXT_texture_edge_clamp on Nvidia.
584       // part of OpenGL 1.2 core
585       // there is no new function with this extension, we don't need to load
586       // it.
587       bool supports_edge_clamp=extensions->ExtensionSupported("GL_VERSION_1_2")==1;
588       if(!supports_edge_clamp)
589         {
590         supports_edge_clamp=extensions->ExtensionSupported("GL_SGIS_texture_edge_clamp")==1;
591         if(!supports_edge_clamp)
592           {
593           // nvidia cards.
594           supports_edge_clamp=extensions->ExtensionSupported("GL_EXT_texture_edge_clamp")==1;
595           }
596         }
597 
598       GLint alphaBits;
599       glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
600       bool supportsAtLeast8AlphaBits=alphaBits>=8;
601 
602       // force alpha blending
603       // Mesa does not support true linking of shaders (VTK bug 8135)
604       // and Mesa 7.2 just crashes during the try-compile.
605       // os mesa 9.1.4 some tests fail
606       // ATI Radeon HD XXXXX on Windows chokes on PROXY_TEXTURE_RECTANGLE_ARB
607       // memory querries however if those are not used all the tests pass.
608       // ATI Radeon HD on Mac OSX PROXY_TEXTURE_RECTANGLE_ARB are fine but
609       // TestTranslucentLUTDepthPeeling fails. So leave it disabled on Apple
610       int driver_support
611         = (!(extensions->DriverIsATI()
612         && (extensions->GetDriverGLVersionMajor() < 3))
613         && !extensions->DriverIsMesa())
614         || extensions->GetIgnoreDriverBugs("ATI and Mesa depth peeling bugs");
615 
616       this->IsSupported =
617         supports_depth_texture &&
618         supports_shadow &&
619         supports_blend_func_separate &&
620         supports_shadow_funcs &&
621         supports_vertex_shader &&
622         supports_fragment_shader &&
623         supports_shader_objects &&
624         supports_occlusion_query &&
625         supports_multitexture &&
626         supports_GL_ARB_texture_rectangle &&
627         supports_edge_clamp &&
628         supportsAtLeast8AlphaBits &&
629         driver_support;
630 
631       if(this->IsSupported)
632         {
633         vtkDebugMacro("depth peeling supported");
634         if(supports_GL_1_3)
635           {
636           extensions->LoadExtension("GL_VERSION_1_3");
637           }
638         else
639           {
640           extensions->LoadCorePromotedExtension("GL_ARB_multitexture");
641           }
642         // GL_ARB_depth_texture, GL_ARB_shadow and GL_EXT_shadow_funcs
643         // don't introduce new functions.
644         if(supports_GL_1_4)
645           {
646           extensions->LoadExtension("GL_VERSION_1_4");
647           }
648         else
649           {
650           extensions->LoadCorePromotedExtension("GL_EXT_blend_func_separate");
651           }
652 
653         if(supports_GL_2_0)
654           {
655           extensions->LoadExtension("GL_VERSION_2_0");
656           }
657         else
658           {
659           extensions->LoadCorePromotedExtension("GL_ARB_vertex_shader");
660           extensions->LoadCorePromotedExtension("GL_ARB_fragment_shader");
661           extensions->LoadCorePromotedExtension("GL_ARB_shader_objects");
662           }
663         if(supports_GL_1_5)
664           {
665           extensions->LoadExtension("GL_VERSION_1_5");
666           }
667         else
668           {
669           extensions->LoadCorePromotedExtension("GL_ARB_occlusion_query");
670           }
671 
672         extensions->LoadExtension("GL_ARB_texture_rectangle");
673 
674         // Some OpenGL implementations such as ATI
675         // claim to support both GLSL and GL_ARB_texture_rectangle but
676         // don't actually support sampler2DRectShadow in a GLSL code.
677         // Others (like Mesa) claim to support shaders but don't actually
678         // support true linking of shaders (and declaration of functions).
679         // To test that, we compile the shader, if it fails, we don't use
680         // deph peeling
681         GLuint shader =
682           vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
683         vtkgl::ShaderSource(
684           shader, 1,
685           const_cast<const char **>(&vtkDepthPeeling_fs), 0);
686         vtkgl::CompileShader(shader);
687         GLint params;
688         vtkgl::GetShaderiv(shader,vtkgl::COMPILE_STATUS,
689                            &params);
690         this->IsSupported = params==GL_TRUE;
691         vtkgl::DeleteShader(shader);
692         if(!this->IsSupported)
693           {
694           vtkDebugMacro("this OpenGL implementation does not support "
695                         "GL_ARB_texture_rectangle in GLSL code or does"
696                         "not support true linking of shaders.");
697           }
698         }
699       else
700         {
701         vtkDebugMacro(<<"depth peeling is not supported.");
702         if(!supports_depth_texture)
703           {
704           vtkDebugMacro(<<"neither OpenGL 1.4 nor GL_ARB_depth_texture is supported");
705           }
706         if(!supports_shadow)
707           {
708           vtkDebugMacro(<<"neither OpenGL 1.4 nor GL_ARB_shadow is supported");
709           }
710         if(!supports_shadow_funcs)
711           {
712           vtkDebugMacro(<<"neither OpenGL 1.5 nor GL_EXT_shadow_funcs is supported");
713           }
714         if(!supports_vertex_shader)
715           {
716           vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_vertex_shader is supported");
717           }
718         if(!supports_fragment_shader)
719           {
720           vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_fragment_shader is supported");
721           }
722         if(!supports_shader_objects)
723           {
724           vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_shader_objects is supported");
725           }
726         if(!supports_occlusion_query)
727           {
728           vtkDebugMacro(<<"neither OpenGL 1.5 nor GL_ARB_occlusion_query is supported");
729           }
730         if(!supports_multitexture)
731           {
732           vtkDebugMacro(<<"neither OpenGL 1.3 nor GL_ARB_multitexture is supported");
733           }
734         if(!supports_GL_ARB_texture_rectangle)
735           {
736           vtkDebugMacro(<<"GL_ARB_texture_rectangle is not supported");
737           }
738         if(!supports_edge_clamp)
739           {
740           vtkDebugMacro(<<"neither OpenGL 1.2 nor GL_SGIS_texture_edge_clamp nor GL_EXT_texture_edge_clamp is not supported");
741           }
742         if(!supportsAtLeast8AlphaBits)
743           {
744           vtkDebugMacro(<<"at least 8 alpha bits is not supported");
745           }
746         if (!driver_support)
747           {
748           vtkDebugMacro(<<"buggy driver (Mesa or ATI)");
749           }
750         }
751     }
752   vtkOpenGLClearErrorMacro();
753 }
754 
755 // ----------------------------------------------------------------------------
756 // Description:
757 // Check the compilation status of some fragment shader source.
CheckCompilation(unsigned int fragmentShader)758 void vtkDepthPeelingPass::CheckCompilation(
759   unsigned int fragmentShader)
760 {
761   GLuint fs=static_cast<GLuint>(fragmentShader);
762   GLint params;
763   vtkgl::GetShaderiv(fs,vtkgl::COMPILE_STATUS,&params);
764   if(params==GL_TRUE)
765     {
766     vtkDebugMacro(<<"shader source compiled successfully");
767     }
768   else
769     {
770     vtkErrorMacro(<<"shader source compile error");
771     // include null terminator
772     vtkgl::GetShaderiv(fs,vtkgl::INFO_LOG_LENGTH,&params);
773     if(params>0)
774       {
775       char *buffer=new char[params];
776       vtkgl::GetShaderInfoLog(fs,params,0,buffer);
777       vtkErrorMacro(<<"log: "<<buffer);
778       delete[] buffer;
779       }
780     else
781       {
782       vtkErrorMacro(<<"no log");
783       }
784     }
785   vtkOpenGLClearErrorMacro();
786 }
787 
788 // ----------------------------------------------------------------------------
789 // Description:
790 // Render a peel layer. If there is no more GPU RAM to save the texture,
791 // return false otherwise returns true. Also if layer==0 and no prop have
792 // been rendered (there is no translucent geometry), it returns false.
793 // \pre s_exists: s!=0
794 // \pre positive_layer: layer>=0
RenderPeel(const vtkRenderState * s,int layer)795 int vtkDepthPeelingPass::RenderPeel(const vtkRenderState *s,
796                                     int layer)
797 {
798   assert("pre: s_exists" && s!=0);
799   assert("pre: positive_layer" && layer>=0);
800 
801   vtkOpenGLClearErrorMacro();
802 
803   GLbitfield mask=GL_COLOR_BUFFER_BIT;
804   if(layer>0)
805     {
806     mask=mask|GL_DEPTH_BUFFER_BIT;
807     }
808 
809   glClearColor(0.0, 0.0, 0.0, 0.0);
810   glClear(mask);
811 
812 //  vtkgl::ActiveTexture(vtkgl::TEXTURE0+this->OpaqueShadowTexUnit);
813 //  glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->OpaqueLayerZ);
814 //  vtkgl::ActiveTexture(vtkgl::TEXTURE0+this->ShadowTexUnit);
815 
816   vtkOpenGLRenderer *oRenderer=
817     static_cast<vtkOpenGLRenderer *>(s->GetRenderer());
818 
819   if(layer>0)
820     {
821     if(layer==1)
822       {
823       // allocate texture units.
824       vtkOpenGLRenderWindow *context
825         = vtkOpenGLRenderWindow::SafeDownCast(this->Prog->GetContext());
826 
827       vtkTextureUnitManager *m = context->GetTextureUnitManager();
828 
829       // Avoid using texture unit 0 because the glBindTexture call's
830       // below must specify unique active textures. If texture unit 0
831       // is used, the ActiveTexture TEXTURE0 and
832       // TEXTURE0+ShadowTextUnit will both select TEXTURE0. Some
833       // platforms, e.g. the Mac, may report the error:
834       // "Samplers of different types use the same texture image unit."
835       int tu;
836       tu = m->Allocate();
837       if (tu == 0)
838         {
839         this->ShadowTexUnit=m->Allocate();
840         }
841       else
842         {
843         this->ShadowTexUnit=tu;
844         }
845       if(this->ShadowTexUnit==-1)
846         {
847         vtkErrorMacro(<<"Ought. No texture unit left!");
848         return 0;
849         }
850       this->OpaqueShadowTexUnit=m->Allocate();
851       if(this->OpaqueShadowTexUnit==-1)
852         {
853         vtkErrorMacro(<<"Ought. No texture unit left!");
854         return 0;
855         }
856       if (tu != this->ShadowTexUnit)
857         {
858         m->Free(tu);
859         }
860       vtkUniformVariables *v=this->Shader->GetUniformVariables();
861       int ivalue;
862       ivalue=this->ShadowTexUnit; // 1
863       v->SetUniformi("shadowTex",1,&ivalue);
864       ivalue=this->OpaqueShadowTexUnit; //2
865       v->SetUniformi("opaqueShadowTex",1,&ivalue);
866       }
867 
868     vtkgl::ActiveTexture(vtkgl::TEXTURE0+this->OpaqueShadowTexUnit);
869     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->OpaqueLayerZ);
870     vtkgl::ActiveTexture(vtkgl::TEXTURE0+this->ShadowTexUnit);
871     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
872     oRenderer->SetShaderProgram(this->Prog);
873 //    this->Prog->Use();
874     }
875 
876   vtkgl::ActiveTexture(vtkgl::TEXTURE0 );
877   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
878   this->DepthPeelingHigherLayer=layer>0;
879   this->TranslucentPass->Render(s);
880   int numberOfRenderedProps=this->TranslucentPass->GetNumberOfRenderedProps();
881   if(layer>0)
882     {
883     this->DepthPeelingHigherLayer=0;
884     oRenderer->SetShaderProgram(0);
885     }
886 
887 //  vtkgl::ActiveTexture(vtkgl::TEXTURE0+this->ShadowTexUnit);
888   if(layer==0)
889     {
890     if(numberOfRenderedProps>0)
891       {
892       GLuint transparentLayerZ;
893       glGenTextures(1,&transparentLayerZ);
894       this->TransparentLayerZ=static_cast<unsigned int>(transparentLayerZ);
895       glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
896 
897       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
898                       GL_NEAREST);
899       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
900                       GL_NEAREST);
901       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,
902                       vtkgl::CLAMP_TO_EDGE);
903       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,
904                       vtkgl::CLAMP_TO_EDGE);
905       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
906                       vtkgl::TEXTURE_COMPARE_MODE,
907                       vtkgl::COMPARE_R_TO_TEXTURE);
908       glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
909                       vtkgl::TEXTURE_COMPARE_FUNC,
910                       GL_GREATER);
911 
912       // Allocate memory. verified that GPU supports
913       // a texture of this size and format above.
914       glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB,0,this->DepthFormat,
915                    this->ViewportWidth,this->ViewportHeight, 0,
916                    GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
917       }
918     }
919   else
920     {
921     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
922     }
923   if((layer==0 && numberOfRenderedProps>0) || layer>0)
924     {
925     // Grab the z-buffer
926     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
927                         this->ViewportY,this->ViewportWidth,
928                         this->ViewportHeight);
929 
930     // Grab the rgba buffer
931     GLuint rgba;
932     glGenTextures(1,&rgba);
933     glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,rgba);
934     // rgba format
935     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
936                     GL_NEAREST);
937     glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
938                     GL_NEAREST);
939 
940     // Allocate memory. verified that GPU supports
941     // a texture of this size and format above.
942     glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
943                  this->ViewportWidth,this->ViewportHeight, 0, GL_RGBA,
944                  GL_UNSIGNED_BYTE, 0);
945 
946     // Grab the rgba-buffer
947     glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
948                         this->ViewportY,this->ViewportWidth,
949                         this->ViewportHeight);
950     this->LayerList->List.push_back(rgba);
951     vtkOpenGLCheckErrorMacro("failed after RenderPeel");
952     return 1;
953     }
954   else
955     {
956     vtkOpenGLCheckErrorMacro("failed after RenderPeel");
957     return 0;
958     }
959 }
960