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