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 "vtkInformation.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkOpenGLActor.h"
20 #include "vtkOpenGLError.h"
21 #include "vtkOpenGLFramebufferObject.h"
22 #include "vtkOpenGLQuadHelper.h"
23 #include "vtkOpenGLRenderWindow.h"
24 #include "vtkOpenGLRenderer.h"
25 #include "vtkOpenGLShaderCache.h"
26 #include "vtkOpenGLState.h"
27 #include "vtkProp.h"
28 #include "vtkRenderState.h"
29 #include "vtkRenderer.h"
30 #include "vtkShaderProgram.h"
31 #include "vtkTextureObject.h"
32 #include <cassert>
33 #include <list>
34 
35 #include "vtkRenderStepsPass.h"
36 
37 #include "vtkOpenGLHelper.h"
38 
39 // the 2D blending shaders we use
40 #include "vtkDepthPeelingPassFinalFS.h"
41 #include "vtkDepthPeelingPassIntermediateFS.h"
42 
43 vtkStandardNewMacro(vtkDepthPeelingPass);
44 vtkCxxSetObjectMacro(vtkDepthPeelingPass, TranslucentPass, vtkRenderPass);
45 
46 //------------------------------------------------------------------------------
vtkDepthPeelingPass()47 vtkDepthPeelingPass::vtkDepthPeelingPass()
48   : Framebuffer(nullptr)
49 {
50   this->TranslucentPass = nullptr;
51 
52   this->OcclusionRatio = 0.0;
53   this->MaximumNumberOfPeels = 4;
54 
55   this->IntermediateBlend = nullptr;
56   this->FinalBlend = nullptr;
57 
58   this->OpaqueRGBATexture = nullptr;
59   this->OpaqueZTexture = nullptr;
60   this->OwnOpaqueZTexture = false;
61   this->OwnOpaqueRGBATexture = false;
62 
63   this->TranslucentZTexture[0] = vtkTextureObject::New();
64   this->TranslucentZTexture[1] = vtkTextureObject::New();
65   this->DepthFormat = vtkTextureObject::Float32;
66 
67   for (int i = 0; i < 3; i++)
68   {
69     this->TranslucentRGBATexture[i] = vtkTextureObject::New();
70   }
71 
72   this->ViewportX = 0;
73   this->ViewportY = 0;
74   this->ViewportWidth = 100;
75   this->ViewportHeight = 100;
76 }
77 
78 //------------------------------------------------------------------------------
~vtkDepthPeelingPass()79 vtkDepthPeelingPass::~vtkDepthPeelingPass()
80 {
81   if (this->TranslucentPass != nullptr)
82   {
83     this->TranslucentPass->Delete();
84   }
85   if (this->OpaqueZTexture)
86   {
87     this->OpaqueZTexture->UnRegister(this);
88     this->OpaqueZTexture = nullptr;
89   }
90   if (this->TranslucentZTexture[0])
91   {
92     this->TranslucentZTexture[0]->UnRegister(this);
93     this->TranslucentZTexture[0] = nullptr;
94   }
95   if (this->TranslucentZTexture[1])
96   {
97     this->TranslucentZTexture[1]->UnRegister(this);
98     this->TranslucentZTexture[1] = nullptr;
99   }
100   if (this->OpaqueRGBATexture)
101   {
102     this->OpaqueRGBATexture->UnRegister(this);
103     this->OpaqueRGBATexture = nullptr;
104   }
105   for (int i = 0; i < 3; i++)
106   {
107     if (this->TranslucentRGBATexture[i])
108     {
109       this->TranslucentRGBATexture[i]->UnRegister(this);
110       this->TranslucentRGBATexture[i] = nullptr;
111     }
112   }
113   if (this->Framebuffer)
114   {
115     this->Framebuffer->UnRegister(this);
116     this->Framebuffer = nullptr;
117   }
118 }
119 
120 //------------------------------------------------------------------------------
121 // Description:
122 // Destructor. Delete SourceCode if any.
ReleaseGraphicsResources(vtkWindow * w)123 void vtkDepthPeelingPass::ReleaseGraphicsResources(vtkWindow* w)
124 {
125   assert("pre: w_exists" && w != nullptr);
126 
127   if (this->FinalBlend != nullptr)
128   {
129     delete this->FinalBlend;
130     this->FinalBlend = nullptr;
131   }
132   if (this->IntermediateBlend != nullptr)
133   {
134     delete this->IntermediateBlend;
135     this->IntermediateBlend = nullptr;
136   }
137   if (this->TranslucentPass)
138   {
139     this->TranslucentPass->ReleaseGraphicsResources(w);
140   }
141   if (this->OpaqueZTexture)
142   {
143     this->OpaqueZTexture->ReleaseGraphicsResources(w);
144   }
145   if (this->TranslucentZTexture[0])
146   {
147     this->TranslucentZTexture[0]->ReleaseGraphicsResources(w);
148   }
149   if (this->TranslucentZTexture[1])
150   {
151     this->TranslucentZTexture[1]->ReleaseGraphicsResources(w);
152   }
153   if (this->OpaqueRGBATexture)
154   {
155     this->OpaqueRGBATexture->ReleaseGraphicsResources(w);
156   }
157   for (int i = 0; i < 3; i++)
158   {
159     if (this->TranslucentRGBATexture[i])
160     {
161       this->TranslucentRGBATexture[i]->ReleaseGraphicsResources(w);
162     }
163   }
164   if (this->Framebuffer)
165   {
166     this->Framebuffer->ReleaseGraphicsResources(w);
167     this->Framebuffer->UnRegister(this);
168     this->Framebuffer = nullptr;
169   }
170 }
171 
SetOpaqueZTexture(vtkTextureObject * to)172 void vtkDepthPeelingPass::SetOpaqueZTexture(vtkTextureObject* to)
173 {
174   if (this->OpaqueZTexture == to)
175   {
176     return;
177   }
178   if (this->OpaqueZTexture)
179   {
180     this->OpaqueZTexture->Delete();
181   }
182   this->OpaqueZTexture = to;
183   if (to)
184   {
185     to->Register(this);
186   }
187   this->OwnOpaqueZTexture = false;
188   this->Modified();
189 }
190 
SetOpaqueRGBATexture(vtkTextureObject * to)191 void vtkDepthPeelingPass::SetOpaqueRGBATexture(vtkTextureObject* to)
192 {
193   if (this->OpaqueRGBATexture == to)
194   {
195     return;
196   }
197   if (this->OpaqueRGBATexture)
198   {
199     this->OpaqueRGBATexture->Delete();
200   }
201   this->OpaqueRGBATexture = to;
202   if (to)
203   {
204     to->Register(this);
205   }
206   this->OwnOpaqueRGBATexture = false;
207   this->Modified();
208 }
209 
210 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)211 void vtkDepthPeelingPass::PrintSelf(ostream& os, vtkIndent indent)
212 {
213   this->Superclass::PrintSelf(os, indent);
214 
215   os << indent << "OcclusionRatio: " << this->OcclusionRatio << endl;
216 
217   os << indent << "MaximumNumberOfPeels: " << this->MaximumNumberOfPeels << endl;
218 
219   os << indent << "TranslucentPass:";
220   if (this->TranslucentPass != nullptr)
221   {
222     this->TranslucentPass->PrintSelf(os, indent);
223   }
224   else
225   {
226     os << "(none)" << endl;
227   }
228 }
229 
vtkDepthPeelingPassCreateTexture(vtkTextureObject * to,vtkOpenGLRenderWindow * context,int width,int height,int numComponents,bool isDepth,int depthFormat)230 void vtkDepthPeelingPassCreateTexture(vtkTextureObject* to, vtkOpenGLRenderWindow* context,
231   int width, int height, int numComponents, bool isDepth, int depthFormat)
232 {
233   to->SetContext(context);
234   if (isDepth == true)
235   {
236     to->AllocateDepth(width, height, depthFormat);
237   }
238   else
239   {
240     to->Allocate2D(width, height, numComponents, VTK_UNSIGNED_CHAR);
241   }
242 
243   to->SetMinificationFilter(vtkTextureObject::Nearest);
244   to->SetMagnificationFilter(vtkTextureObject::Nearest);
245   to->SetWrapS(vtkTextureObject::ClampToEdge);
246   to->SetWrapT(vtkTextureObject::ClampToEdge);
247 }
248 
BlendIntermediatePeels(vtkOpenGLRenderWindow * renWin,bool done)249 void vtkDepthPeelingPass::BlendIntermediatePeels(vtkOpenGLRenderWindow* renWin, bool done)
250 {
251   // take the TranslucentRGBA texture and blend it with the current frame buffer
252   if (!this->IntermediateBlend)
253   {
254     this->IntermediateBlend =
255       new vtkOpenGLQuadHelper(renWin, nullptr, vtkDepthPeelingPassIntermediateFS, "");
256   }
257   else
258   {
259     renWin->GetShaderCache()->ReadyShaderProgram(this->IntermediateBlend->Program);
260   }
261   this->IntermediateBlend->Program->SetUniformi("translucentRGBATexture",
262     this->TranslucentRGBATexture[(this->ColorDrawCount - 2) % 3]->GetTextureUnit());
263   this->IntermediateBlend->Program->SetUniformi("currentRGBATexture",
264     this->TranslucentRGBATexture[(this->ColorDrawCount - 1) % 3]->GetTextureUnit());
265   this->IntermediateBlend->Program->SetUniformi("lastpass", done ? 1 : 0);
266 
267   this->State->vtkglDisable(GL_DEPTH_TEST);
268 
269   this->Framebuffer->AddColorAttachment(0, this->TranslucentRGBATexture[this->ColorDrawCount % 3]);
270   this->ColorDrawCount++;
271 
272   this->IntermediateBlend->Render();
273 }
274 
BlendFinalPeel(vtkOpenGLRenderWindow * renWin)275 void vtkDepthPeelingPass::BlendFinalPeel(vtkOpenGLRenderWindow* renWin)
276 {
277   if (!this->FinalBlend)
278   {
279     this->FinalBlend = new vtkOpenGLQuadHelper(renWin, nullptr, vtkDepthPeelingPassFinalFS, "");
280   }
281   else
282   {
283     renWin->GetShaderCache()->ReadyShaderProgram(this->FinalBlend->Program);
284   }
285 
286   if (this->FinalBlend->Program)
287   {
288     this->FinalBlend->Program->SetUniformi("translucentRGBATexture",
289       this->TranslucentRGBATexture[(this->ColorDrawCount - 1) % 3]->GetTextureUnit());
290 
291     // Store the current active texture
292     vtkOpenGLState::ScopedglActiveTexture activeTexture(this->State);
293 
294     this->OpaqueRGBATexture->Activate();
295     this->FinalBlend->Program->SetUniformi(
296       "opaqueRGBATexture", this->OpaqueRGBATexture->GetTextureUnit());
297 
298     this->OpaqueZTexture->Activate();
299     this->FinalBlend->Program->SetUniformi(
300       "opaqueZTexture", this->OpaqueZTexture->GetTextureUnit());
301 
302     this->Framebuffer->AddColorAttachment(
303       0, this->TranslucentRGBATexture[this->ColorDrawCount % 3]);
304     this->ColorDrawCount++;
305 
306     // blend in OpaqueRGBA
307     this->State->vtkglEnable(GL_DEPTH_TEST);
308     this->State->vtkglDepthFunc(GL_ALWAYS);
309 
310     // do we need to set the viewport
311     this->FinalBlend->Render();
312   }
313   this->State->vtkglDepthFunc(GL_LEQUAL);
314 }
315 
316 //------------------------------------------------------------------------------
317 // Description:
318 // Perform rendering according to a render state \p s.
319 // \pre s_exists: s!=0
Render(const vtkRenderState * s)320 void vtkDepthPeelingPass::Render(const vtkRenderState* s)
321 {
322   assert("pre: s_exists" && s != nullptr);
323 
324   this->NumberOfRenderedProps = 0;
325 
326   if (this->TranslucentPass == nullptr)
327   {
328     vtkWarningMacro(<< "No TranslucentPass delegate set. Nothing can be rendered.");
329     return;
330   }
331 
332   // Any prop to render?
333   bool hasTranslucentPolygonalGeometry = false;
334   int i = 0;
335   while (!hasTranslucentPolygonalGeometry && i < s->GetPropArrayCount())
336   {
337     hasTranslucentPolygonalGeometry = s->GetPropArray()[i]->HasTranslucentPolygonalGeometry() == 1;
338     ++i;
339   }
340   if (!hasTranslucentPolygonalGeometry)
341   {
342     return; // nothing to render.
343   }
344 
345   // check driver support
346   vtkOpenGLRenderWindow* renWin =
347     vtkOpenGLRenderWindow::SafeDownCast(s->GetRenderer()->GetRenderWindow());
348   this->State = renWin->GetState();
349 
350   // we need alpha planes
351   int rgba[4];
352   renWin->GetColorBufferSizes(rgba);
353 
354   if (rgba[3] < 8)
355   {
356     // just use alpha blending
357     this->TranslucentPass->Render(s);
358     return;
359   }
360 
361   // Depth peeling.
362   vtkRenderer* r = s->GetRenderer();
363 
364   if (s->GetFrameBuffer() == nullptr)
365   {
366     // get the viewport dimensions
367     r->GetTiledSizeAndOrigin(
368       &this->ViewportWidth, &this->ViewportHeight, &this->ViewportX, &this->ViewportY);
369   }
370   else
371   {
372     int size[2];
373     s->GetWindowSize(size);
374     this->ViewportWidth = size[0];
375     this->ViewportHeight = size[1];
376     this->ViewportX = 0;
377     this->ViewportY = 0;
378   }
379 
380   // create textures we need if not done already
381   if (this->TranslucentRGBATexture[0]->GetHandle() == 0)
382   {
383     for (i = 0; i < 3; i++)
384     {
385       vtkDepthPeelingPassCreateTexture(this->TranslucentRGBATexture[i], renWin, this->ViewportWidth,
386         this->ViewportHeight, 4, false, 0);
387     }
388     vtkDepthPeelingPassCreateTexture(this->TranslucentZTexture[0], renWin, this->ViewportWidth,
389       this->ViewportHeight, 1, true, this->DepthFormat);
390     vtkDepthPeelingPassCreateTexture(this->TranslucentZTexture[1], renWin, this->ViewportWidth,
391       this->ViewportHeight, 1, true, this->DepthFormat);
392     if (!this->OpaqueZTexture)
393     {
394       this->OwnOpaqueZTexture = true;
395       this->OpaqueZTexture = vtkTextureObject::New();
396       vtkDepthPeelingPassCreateTexture(this->OpaqueZTexture, renWin, this->ViewportWidth,
397         this->ViewportHeight, 1, true, this->DepthFormat);
398     }
399     if (!this->OpaqueRGBATexture)
400     {
401       this->OwnOpaqueRGBATexture = true;
402       this->OpaqueRGBATexture = vtkTextureObject::New();
403       vtkDepthPeelingPassCreateTexture(
404         this->OpaqueRGBATexture, renWin, this->ViewportWidth, this->ViewportHeight, 4, false, 0);
405     }
406   }
407 
408   for (i = 0; i < 3; i++)
409   {
410     this->TranslucentRGBATexture[i]->Resize(this->ViewportWidth, this->ViewportHeight);
411   }
412   this->TranslucentZTexture[0]->Resize(this->ViewportWidth, this->ViewportHeight);
413   this->TranslucentZTexture[1]->Resize(this->ViewportWidth, this->ViewportHeight);
414 
415   if (this->OwnOpaqueZTexture)
416   {
417     this->OpaqueZTexture->Resize(this->ViewportWidth, this->ViewportHeight);
418     this->OpaqueZTexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY, this->ViewportX,
419       this->ViewportY, this->ViewportWidth, this->ViewportHeight);
420   }
421 
422   if (this->OwnOpaqueRGBATexture)
423   {
424     this->OpaqueRGBATexture->Resize(this->ViewportWidth, this->ViewportHeight);
425     this->OpaqueRGBATexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY, this->ViewportX,
426       this->ViewportY, this->ViewportWidth, this->ViewportHeight);
427   }
428 
429   if (!this->Framebuffer)
430   {
431     this->Framebuffer = vtkOpenGLFramebufferObject::New();
432     this->Framebuffer->SetContext(renWin);
433   }
434   this->State->PushFramebufferBindings();
435   this->Framebuffer->Bind();
436   this->Framebuffer->AddDepthAttachment(this->TranslucentZTexture[0]);
437   this->Framebuffer->AddColorAttachment(0, this->TranslucentRGBATexture[0]);
438 
439   this->State->vtkglViewport(0, 0, this->ViewportWidth, this->ViewportHeight);
440   bool saveScissorTestState = this->State->GetEnumState(GL_SCISSOR_TEST);
441   this->State->vtkglDisable(GL_SCISSOR_TEST);
442 
443   this->State->vtkglClearDepth(static_cast<GLclampf>(0.0));
444   this->State->vtkglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
445 
446   this->State->vtkglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
447   this->State->vtkglClearColor(0.0, 0.0, 0.0, 0.0); // always clear to black
448   this->State->vtkglClearDepth(static_cast<GLclampf>(1.0));
449   // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
450 
451   this->Framebuffer->AddDepthAttachment(this->TranslucentZTexture[1]);
452   this->State->vtkglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
453 
454 #ifdef GL_MULTISAMPLE
455   bool multiSampleStatus = this->State->GetEnumState(GL_MULTISAMPLE);
456   this->State->vtkglDisable(GL_MULTISAMPLE);
457 #endif
458   this->State->vtkglDisable(GL_BLEND);
459 
460   // Store the current active texture
461   vtkOpenGLState::ScopedglActiveTexture activeTexture(this->State);
462 
463   this->TranslucentZTexture[0]->Activate();
464   this->OpaqueZTexture->Activate();
465 
466   this->TranslucentRGBATexture[0]->Activate();
467   this->TranslucentRGBATexture[1]->Activate();
468   this->TranslucentRGBATexture[2]->Activate();
469 
470   // Setup property keys for actors:
471   this->PreRender(s);
472 
473   // Enable the depth buffer (otherwise it's disabled for translucent geometry)
474   assert("Render state valid." && s);
475   int numProps = s->GetPropArrayCount();
476   for (int j = 0; j < numProps; ++j)
477   {
478     vtkProp* prop = s->GetPropArray()[j];
479     vtkInformation* info = prop->GetPropertyKeys();
480     if (!info)
481     {
482       info = vtkInformation::New();
483       prop->SetPropertyKeys(info);
484       info->FastDelete();
485     }
486     info->Set(vtkOpenGLActor::GLDepthMaskOverride(), 1);
487   }
488 
489   // Do render loop until complete
490   unsigned int threshold =
491     static_cast<unsigned int>(this->ViewportWidth * this->ViewportHeight * OcclusionRatio);
492 
493 #ifndef GL_ES_VERSION_3_0
494   GLuint queryId;
495   glGenQueries(1, &queryId);
496 #endif
497 
498   bool done = false;
499   GLuint nbPixels = threshold + 1;
500   this->PeelCount = 0;
501   this->ColorDrawCount = 0;
502   this->State->vtkglDepthFunc(GL_LEQUAL);
503   while (!done)
504   {
505     this->State->vtkglDepthMask(GL_TRUE);
506     this->State->vtkglEnable(GL_DEPTH_TEST);
507 
508     this->Framebuffer->AddColorAttachment(
509       0, this->TranslucentRGBATexture[this->ColorDrawCount % 3]);
510     this->ColorDrawCount++;
511 
512     // clear the zbuffer and color buffers
513     this->State->vtkglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
514 
515     // render the translucent geometry
516 #ifndef GL_ES_VERSION_3_0
517     glBeginQuery(GL_SAMPLES_PASSED, queryId);
518 #endif
519 
520     // check if we are going to exceed the max number of peels or if we
521     // exceeded the pixel threshold last time
522     this->PeelCount++;
523     if ((this->MaximumNumberOfPeels && this->PeelCount >= this->MaximumNumberOfPeels) ||
524       nbPixels <= threshold)
525     {
526       done = true;
527       // if so we do this last render using alpha blending for all
528       // the stuff that is left
529       this->State->vtkglEnable(GL_BLEND);
530       this->State->vtkglDepthFunc(GL_ALWAYS);
531     }
532     this->TranslucentPass->Render(s);
533     this->State->vtkglDepthFunc(GL_LEQUAL);
534     this->State->vtkglDisable(GL_BLEND);
535 
536 #ifndef GL_ES_VERSION_3_0
537     glEndQuery(GL_SAMPLES_PASSED);
538     glGetQueryObjectuiv(queryId, GL_QUERY_RESULT, &nbPixels);
539 #endif
540     // cerr << "Pass " << peelCount << " pixels Drawn " << nbPixels << "\n";
541 
542     // if something was drawn, blend it in
543     if (nbPixels > 0)
544     {
545       // update translucentZ pingpong the textures
546       if (this->PeelCount % 2)
547       {
548         this->TranslucentZTexture[0]->Deactivate();
549         this->Framebuffer->AddDepthAttachment(this->TranslucentZTexture[0]);
550         this->TranslucentZTexture[1]->Activate();
551       }
552       else
553       {
554         this->TranslucentZTexture[1]->Deactivate();
555         this->Framebuffer->AddDepthAttachment(this->TranslucentZTexture[1]);
556         this->TranslucentZTexture[0]->Activate();
557       }
558 
559       // blend the last two peels together
560       if (this->PeelCount > 1)
561       {
562         this->BlendIntermediatePeels(renWin, done);
563       }
564     }
565     else // if we drew nothing we are done
566     {
567       this->ColorDrawCount--;
568       done = true;
569     }
570   }
571 
572   //  std::cout << "Number of peels: " << peelCount << "\n";
573 
574   // do the final blend if anything was drawn
575   // something is drawn only when ColorDrawCount
576   // is not zero or PeelCount is > 1
577   if (this->PeelCount > 1 || this->ColorDrawCount != 0)
578   {
579     this->BlendFinalPeel(renWin);
580   }
581 
582   this->State->PopFramebufferBindings();
583 
584   // Restore the original viewport and scissor test settings
585   this->State->vtkglViewport(
586     this->ViewportX, this->ViewportY, this->ViewportWidth, this->ViewportHeight);
587   if (saveScissorTestState)
588   {
589     this->State->vtkglEnable(GL_SCISSOR_TEST);
590   }
591   else
592   {
593     this->State->vtkglDisable(GL_SCISSOR_TEST);
594   }
595 
596   // blit if we drew something
597   if (this->PeelCount > 1 || this->ColorDrawCount != 0)
598   {
599     this->State->PushReadFramebufferBinding();
600     this->Framebuffer->Bind(vtkOpenGLFramebufferObject::GetReadMode());
601 
602     this->State->vtkglBlitFramebuffer(0, 0, this->ViewportWidth, this->ViewportHeight,
603       this->ViewportX, this->ViewportY, this->ViewportX + this->ViewportWidth,
604       this->ViewportY + this->ViewportHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
605 
606     this->State->PopReadFramebufferBinding();
607   }
608 
609 #ifdef GL_MULTISAMPLE
610   if (multiSampleStatus)
611   {
612     this->State->vtkglEnable(GL_MULTISAMPLE);
613   }
614 #endif
615 
616   // unload the textures
617   this->OpaqueZTexture->Deactivate();
618   this->OpaqueRGBATexture->Deactivate();
619   this->TranslucentRGBATexture[0]->Deactivate();
620   this->TranslucentRGBATexture[1]->Deactivate();
621   this->TranslucentRGBATexture[2]->Deactivate();
622   this->TranslucentZTexture[0]->Deactivate();
623   this->TranslucentZTexture[1]->Deactivate();
624 
625   // restore blending
626   this->State->vtkglEnable(GL_BLEND);
627 
628   this->PostRender(s);
629   for (int j = 0; j < numProps; ++j)
630   {
631     vtkProp* prop = s->GetPropArray()[j];
632     vtkInformation* info = prop->GetPropertyKeys();
633     if (info)
634     {
635       info->Remove(vtkOpenGLActor::GLDepthMaskOverride());
636     }
637   }
638 
639   this->NumberOfRenderedProps = this->TranslucentPass->GetNumberOfRenderedProps();
640 
641   vtkOpenGLCheckErrorMacro("failed after Render");
642 }
643 
644 //------------------------------------------------------------------------------
PostReplaceShaderValues(std::string &,std::string &,std::string & fragmentShader,vtkAbstractMapper *,vtkProp *)645 bool vtkDepthPeelingPass::PostReplaceShaderValues(
646   std::string&, std::string&, std::string& fragmentShader, vtkAbstractMapper*, vtkProp*)
647 {
648   vtkShaderProgram::Substitute(fragmentShader, "//VTK::DepthPeeling::Dec",
649     "uniform vec2 vpSize;\n"
650     "uniform sampler2D opaqueZTexture;\n"
651     "uniform sampler2D translucentZTexture;\n");
652 
653   // Set gl_FragDepth if it isn't set already. It may have already been replaced
654   // by the mapper, in which case the substitution will fail and the previously
655   // set depth value will be used.
656   vtkShaderProgram::Substitute(
657     fragmentShader, "//VTK::Depth::Impl", "gl_FragDepth = gl_FragCoord.z;");
658 
659   // the .0000001 below is an epsilon.  It turns out that
660   // graphics cards can render the same polygon two times
661   // in a row with different z values. I suspect it has to
662   // do with how rasterization of the polygon is broken up.
663   // A different breakup across fragment shaders can result in
664   // very slightly different z values for some of the pixels.
665   // The end result is that with depth peeling, you can end up
666   // counting/accumulating pixels of the same surface twice
667   // simply due to this randomness in z values. So we introduce
668   // an epsilon into the transparent test to require some
669   // minimal z separation between pixels
670   vtkShaderProgram::Substitute(fragmentShader, "//VTK::DepthPeeling::Impl",
671     "vec2 dpTexCoord = gl_FragCoord.xy / vpSize;\n"
672     "  float odepth = texture2D(opaqueZTexture, dpTexCoord).r;\n"
673     "  if (gl_FragDepth >= odepth) { discard; }\n"
674     "  float tdepth = texture2D(translucentZTexture, dpTexCoord).r;\n"
675     "  if (gl_FragDepth <= tdepth + .0000001) { discard; }\n");
676 
677   return true;
678 }
679 
680 //------------------------------------------------------------------------------
SetShaderParameters(vtkShaderProgram * program,vtkAbstractMapper *,vtkProp *,vtkOpenGLVertexArrayObject * vtkNotUsed (VAO))681 bool vtkDepthPeelingPass::SetShaderParameters(vtkShaderProgram* program, vtkAbstractMapper*,
682   vtkProp*, vtkOpenGLVertexArrayObject* vtkNotUsed(VAO))
683 {
684   program->SetUniformi("opaqueZTexture", this->OpaqueZTexture->GetTextureUnit());
685   program->SetUniformi(
686     "translucentZTexture", this->TranslucentZTexture[(this->PeelCount + 1) % 2]->GetTextureUnit());
687 
688   float vpSize[2] = { static_cast<float>(this->ViewportWidth),
689     static_cast<float>(this->ViewportHeight) };
690   program->SetUniform2f("vpSize", vpSize);
691 
692   return true;
693 }
694