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 "vtkOpenGLFramebufferObject.h"
18 #include "vtkInformation.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkOpenGLActor.h"
21 #include "vtkOpenGLError.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 "vtkDepthPeelingPassIntermediateFS.h"
41 #include "vtkDepthPeelingPassFinalFS.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 }
172
SetOpaqueZTexture(vtkTextureObject * to)173 void vtkDepthPeelingPass::SetOpaqueZTexture(vtkTextureObject *to)
174 {
175 if (this->OpaqueZTexture == to)
176 {
177 return;
178 }
179 if (this->OpaqueZTexture)
180 {
181 this->OpaqueZTexture->Delete();
182 }
183 this->OpaqueZTexture = to;
184 if (to)
185 {
186 to->Register(this);
187 }
188 this->OwnOpaqueZTexture = false;
189 this->Modified();
190 }
191
SetOpaqueRGBATexture(vtkTextureObject * to)192 void vtkDepthPeelingPass::SetOpaqueRGBATexture(vtkTextureObject *to)
193 {
194 if (this->OpaqueRGBATexture == to)
195 {
196 return;
197 }
198 if (this->OpaqueRGBATexture)
199 {
200 this->OpaqueRGBATexture->Delete();
201 }
202 this->OpaqueRGBATexture = to;
203 if (to)
204 {
205 to->Register(this);
206 }
207 this->OwnOpaqueRGBATexture = false;
208 this->Modified();
209 }
210
211 // ----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)212 void vtkDepthPeelingPass::PrintSelf(ostream& os, vtkIndent indent)
213 {
214 this->Superclass::PrintSelf(os,indent);
215
216 os << indent << "OcclusionRatio: " << this->OcclusionRatio << endl;
217
218 os << indent << "MaximumNumberOfPeels: " << this->MaximumNumberOfPeels
219 << endl;
220
221 os << indent << "TranslucentPass:";
222 if(this->TranslucentPass!=nullptr)
223 {
224 this->TranslucentPass->PrintSelf(os,indent);
225 }
226 else
227 {
228 os << "(none)" <<endl;
229 }
230 }
231
vtkDepthPeelingPassCreateTexture(vtkTextureObject * to,vtkOpenGLRenderWindow * context,int width,int height,int numComponents,bool isDepth,int depthFormat)232 void vtkDepthPeelingPassCreateTexture(
233 vtkTextureObject *to,
234 vtkOpenGLRenderWindow *context, int width, int height,
235 int numComponents, bool isDepth, int depthFormat)
236 {
237 to->SetContext(context);
238 if (isDepth == true)
239 {
240 to->AllocateDepth(width, height, depthFormat);
241 }
242 else
243 {
244 to->Allocate2D(width, height, numComponents, VTK_UNSIGNED_CHAR);
245 }
246
247 to->SetMinificationFilter(vtkTextureObject::Nearest);
248 to->SetMagnificationFilter(vtkTextureObject::Nearest);
249 to->SetWrapS(vtkTextureObject::ClampToEdge);
250 to->SetWrapT(vtkTextureObject::ClampToEdge);
251 }
252
BlendIntermediatePeels(vtkOpenGLRenderWindow * renWin,bool done)253 void vtkDepthPeelingPass::BlendIntermediatePeels(
254 vtkOpenGLRenderWindow *renWin,
255 bool done)
256 {
257 // take the TranslucentRGBA texture and blend it with the current frame buffer
258 if (!this->IntermediateBlend)
259 {
260 this->IntermediateBlend = new vtkOpenGLQuadHelper(renWin,
261 nullptr,
262 vtkDepthPeelingPassIntermediateFS,
263 "");
264 }
265 else
266 {
267 renWin->GetShaderCache()->ReadyShaderProgram(
268 this->IntermediateBlend->Program);
269 }
270 this->IntermediateBlend->Program->SetUniformi(
271 "translucentRGBATexture",
272 this->TranslucentRGBATexture[(this->ColorDrawCount - 2) % 3]->GetTextureUnit());
273 this->IntermediateBlend->Program->SetUniformi(
274 "currentRGBATexture",
275 this->TranslucentRGBATexture[(this->ColorDrawCount - 1) % 3]->GetTextureUnit());
276 this->IntermediateBlend->Program->SetUniformi(
277 "lastpass", done ? 1 : 0);
278
279 this->State->vtkglDisable(GL_DEPTH_TEST);
280
281 this->Framebuffer->AddColorAttachment(
282 this->Framebuffer->GetBothMode(), 0,
283 this->TranslucentRGBATexture[this->ColorDrawCount % 3]);
284 this->ColorDrawCount++;
285
286 this->IntermediateBlend->Render();
287 }
288
BlendFinalPeel(vtkOpenGLRenderWindow * renWin)289 void vtkDepthPeelingPass::BlendFinalPeel(vtkOpenGLRenderWindow *renWin)
290 {
291 if (!this->FinalBlend)
292 {
293 this->FinalBlend = new vtkOpenGLQuadHelper(renWin,
294 nullptr,
295 vtkDepthPeelingPassFinalFS,
296 "");
297 }
298 else
299 {
300 renWin->GetShaderCache()->ReadyShaderProgram(
301 this->FinalBlend->Program);
302 }
303
304 if (this->FinalBlend->Program)
305 {
306 this->FinalBlend->Program->SetUniformi(
307 "translucentRGBATexture",
308 this->TranslucentRGBATexture[(this->ColorDrawCount - 1) % 3]->GetTextureUnit());
309
310 this->OpaqueRGBATexture->Activate();
311 this->FinalBlend->Program->SetUniformi(
312 "opaqueRGBATexture", this->OpaqueRGBATexture->GetTextureUnit());
313
314 this->OpaqueZTexture->Activate();
315 this->FinalBlend->Program->SetUniformi(
316 "opaqueZTexture", this->OpaqueZTexture->GetTextureUnit());
317
318 this->Framebuffer->AddColorAttachment(
319 this->Framebuffer->GetBothMode(), 0,
320 this->TranslucentRGBATexture[this->ColorDrawCount % 3]);
321 this->ColorDrawCount++;
322
323 // blend in OpaqueRGBA
324 this->State->vtkglEnable(GL_DEPTH_TEST);
325 this->State->vtkglDepthFunc( GL_ALWAYS );
326
327 // do we need to set the viewport
328 this->FinalBlend->Render();
329 }
330 this->State->vtkglDepthFunc( GL_LEQUAL );
331 }
332
333
334 // ----------------------------------------------------------------------------
335 // Description:
336 // Perform rendering according to a render state \p s.
337 // \pre s_exists: s!=0
Render(const vtkRenderState * s)338 void vtkDepthPeelingPass::Render(const vtkRenderState *s)
339 {
340 assert("pre: s_exists" && s!=nullptr);
341
342 this->NumberOfRenderedProps=0;
343
344 if(this->TranslucentPass==nullptr)
345 {
346 vtkWarningMacro(<<"No TranslucentPass delegate set. Nothing can be rendered.");
347 return;
348 }
349
350 // Any prop to render?
351 bool hasTranslucentPolygonalGeometry=false;
352 int i=0;
353 while(!hasTranslucentPolygonalGeometry && i<s->GetPropArrayCount())
354 {
355 hasTranslucentPolygonalGeometry=
356 s->GetPropArray()[i]->HasTranslucentPolygonalGeometry()==1;
357 ++i;
358 }
359 if(!hasTranslucentPolygonalGeometry)
360 {
361 return; // nothing to render.
362 }
363
364 // check driver support
365 vtkOpenGLRenderWindow *renWin
366 = vtkOpenGLRenderWindow::SafeDownCast(s->GetRenderer()->GetRenderWindow());
367 this->State = renWin->GetState();
368
369 // we need alpha planes
370 int rgba[4];
371 renWin->GetColorBufferSizes(rgba);
372
373 if (rgba[3] < 8)
374 {
375 // just use alpha blending
376 this->TranslucentPass->Render(s);
377 return;
378 }
379
380 // Depth peeling.
381 vtkRenderer *r=s->GetRenderer();
382
383 if(s->GetFrameBuffer()==nullptr)
384 {
385 // get the viewport dimensions
386 r->GetTiledSizeAndOrigin(&this->ViewportWidth,&this->ViewportHeight,
387 &this->ViewportX,&this->ViewportY);
388 }
389 else
390 {
391 int size[2];
392 s->GetWindowSize(size);
393 this->ViewportWidth=size[0];
394 this->ViewportHeight=size[1];
395 this->ViewportX=0;
396 this->ViewportY=0;
397 }
398
399 // create textures we need if not done already
400 if (this->TranslucentRGBATexture[0]->GetHandle() == 0)
401 {
402 for (i = 0; i < 3; i++)
403 {
404 vtkDepthPeelingPassCreateTexture(
405 this->TranslucentRGBATexture[i],
406 renWin, this->ViewportWidth, this->ViewportHeight,
407 4, false, 0);
408 }
409 vtkDepthPeelingPassCreateTexture(
410 this->TranslucentZTexture[0],
411 renWin, this->ViewportWidth, this->ViewportHeight, 1, true, this->DepthFormat);
412 vtkDepthPeelingPassCreateTexture(
413 this->TranslucentZTexture[1],
414 renWin, this->ViewportWidth, this->ViewportHeight, 1, true, this->DepthFormat);
415 if (!this->OpaqueZTexture)
416 {
417 this->OwnOpaqueZTexture = true;
418 this->OpaqueZTexture = vtkTextureObject::New();
419 vtkDepthPeelingPassCreateTexture(
420 this->OpaqueZTexture,
421 renWin, this->ViewportWidth, this->ViewportHeight, 1, true, this->DepthFormat);
422 }
423 if (!this->OpaqueRGBATexture)
424 {
425 this->OwnOpaqueRGBATexture = true;
426 this->OpaqueRGBATexture = vtkTextureObject::New();
427 vtkDepthPeelingPassCreateTexture(
428 this->OpaqueRGBATexture,
429 renWin, this->ViewportWidth, this->ViewportHeight,
430 4, false, 0);
431 }
432 }
433
434 for (i = 0; i < 3; i++)
435 {
436 this->TranslucentRGBATexture[i]->Resize(
437 this->ViewportWidth, this->ViewportHeight);
438 }
439 this->TranslucentZTexture[0]->Resize(
440 this->ViewportWidth, this->ViewportHeight);
441 this->TranslucentZTexture[1]->Resize(
442 this->ViewportWidth, this->ViewportHeight);
443
444 if (this->OwnOpaqueZTexture)
445 {
446 this->OpaqueZTexture->Resize(
447 this->ViewportWidth, this->ViewportHeight);
448 this->OpaqueZTexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
449 this->ViewportX, this->ViewportY,
450 this->ViewportWidth, this->ViewportHeight);
451 }
452
453 if (this->OwnOpaqueRGBATexture)
454 {
455 this->OpaqueRGBATexture->Resize(
456 this->ViewportWidth, this->ViewportHeight);
457 this->OpaqueRGBATexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
458 this->ViewportX, this->ViewportY,
459 this->ViewportWidth, this->ViewportHeight);
460 }
461
462 if (!this->Framebuffer)
463 {
464 this->Framebuffer = vtkOpenGLFramebufferObject::New();
465 this->Framebuffer->SetContext(renWin);
466 }
467 this->Framebuffer->SaveCurrentBindingsAndBuffers();
468 this->Framebuffer->Bind();
469 this->Framebuffer->AddDepthAttachment(
470 this->Framebuffer->GetBothMode(), this->TranslucentZTexture[0]);
471 this->Framebuffer->AddColorAttachment(
472 this->Framebuffer->GetBothMode(), 0,
473 this->TranslucentRGBATexture[0]);
474
475 this->State->vtkglViewport(0, 0,
476 this->ViewportWidth, this->ViewportHeight);
477 bool saveScissorTestState = this->State->GetEnumState(GL_SCISSOR_TEST);
478 this->State->vtkglDisable(GL_SCISSOR_TEST);
479
480 this->State->vtkglClearDepth(static_cast<GLclampf>(0.0));
481 this->State->vtkglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
482
483 this->State->vtkglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
484 this->State->vtkglClearColor(0.0,0.0,0.0,0.0); // always clear to black
485 this->State->vtkglClearDepth(static_cast<GLclampf>(1.0));
486 // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
487
488 this->Framebuffer->AddDepthAttachment(
489 this->Framebuffer->GetBothMode(),
490 this->TranslucentZTexture[1]);
491 this->State->vtkglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
492
493 #ifdef GL_MULTISAMPLE
494 bool multiSampleStatus = this->State->GetEnumState(GL_MULTISAMPLE);
495 this->State->vtkglDisable(GL_MULTISAMPLE);
496 #endif
497 this->State->vtkglDisable(GL_BLEND);
498
499 this->TranslucentZTexture[0]->Activate();
500 this->OpaqueZTexture->Activate();
501
502 this->TranslucentRGBATexture[0]->Activate();
503 this->TranslucentRGBATexture[1]->Activate();
504 this->TranslucentRGBATexture[2]->Activate();
505
506 // Setup property keys for actors:
507 this->PreRender(s);
508
509 // Enable the depth buffer (otherwise it's disabled for translucent geometry)
510 assert("Render state valid." && s);
511 int numProps = s->GetPropArrayCount();
512 for (int j = 0; j < numProps; ++j)
513 {
514 vtkProp *prop = s->GetPropArray()[j];
515 vtkInformation *info = prop->GetPropertyKeys();
516 if (!info)
517 {
518 info = vtkInformation::New();
519 prop->SetPropertyKeys(info);
520 info->FastDelete();
521 }
522 info->Set(vtkOpenGLActor::GLDepthMaskOverride(), 1);
523 }
524
525 // Do render loop until complete
526 unsigned int threshold=
527 static_cast<unsigned int>(
528 this->ViewportWidth*this->ViewportHeight*OcclusionRatio);
529
530 #if GL_ES_VERSION_3_0 != 1
531 GLuint queryId;
532 glGenQueries(1,&queryId);
533 #endif
534
535 bool done = false;
536 GLuint nbPixels = threshold + 1;
537 this->PeelCount = 0;
538 this->ColorDrawCount = 0;
539 this->State->vtkglDepthFunc( GL_LEQUAL );
540 while(!done)
541 {
542 this->State->vtkglDepthMask(GL_TRUE);
543 this->State->vtkglEnable(GL_DEPTH_TEST);
544
545 this->Framebuffer->AddColorAttachment(
546 this->Framebuffer->GetBothMode(), 0,
547 this->TranslucentRGBATexture[this->ColorDrawCount % 3]);
548 this->ColorDrawCount++;
549
550 // clear the zbuffer and color buffers
551 this->State->vtkglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
552
553 // render the translucent geometry
554 #if GL_ES_VERSION_3_0 != 1
555 glBeginQuery(GL_SAMPLES_PASSED,queryId);
556 #endif
557
558 // check if we are going to exceed the max number of peels or if we
559 // exceeded the pixel threshold last time
560 this->PeelCount++;
561 if ((this->MaximumNumberOfPeels && this->PeelCount >= this->MaximumNumberOfPeels) ||
562 nbPixels <= threshold)
563 {
564 done = true;
565 // if so we do this last render using alpha blending for all
566 // the stuff that is left
567 this->State->vtkglEnable(GL_BLEND);
568 this->State->vtkglDepthFunc( GL_ALWAYS );
569 }
570 this->TranslucentPass->Render(s);
571 this->State->vtkglDepthFunc( GL_LEQUAL );
572 this->State->vtkglDisable(GL_BLEND);
573
574 #if GL_ES_VERSION_3_0 != 1
575 glEndQuery(GL_SAMPLES_PASSED);
576 glGetQueryObjectuiv(queryId,GL_QUERY_RESULT,&nbPixels);
577 #endif
578 // cerr << "Pass " << peelCount << " pixels Drawn " << nbPixels << "\n";
579
580 // if something was drawn, blend it in
581 if (nbPixels > 0)
582 {
583 // update translucentZ pingpong the textures
584 if (this->PeelCount % 2)
585 {
586 this->TranslucentZTexture[0]->Deactivate();
587 this->Framebuffer->AddDepthAttachment(
588 this->Framebuffer->GetBothMode(), this->TranslucentZTexture[0]);
589 this->TranslucentZTexture[1]->Activate();
590 }
591 else
592 {
593 this->TranslucentZTexture[1]->Deactivate();
594 this->Framebuffer->AddDepthAttachment(
595 this->Framebuffer->GetBothMode(), this->TranslucentZTexture[1]);
596 this->TranslucentZTexture[0]->Activate();
597 }
598
599 // blend the last two peels together
600 if (this->PeelCount > 1)
601 {
602 this->BlendIntermediatePeels(renWin,done);
603 }
604 }
605 else // if we drew nothing we are done
606 {
607 this->ColorDrawCount--;
608 done = true;
609 }
610 }
611
612 // std::cout << "Number of peels: " << peelCount << "\n";
613
614 // do the final blend if anything was drawn
615 // something is drawn only when ColorDrawCount
616 // is not zero or PeelCount is > 1
617 if (this->PeelCount > 1 || this->ColorDrawCount != 0)
618 {
619 this->BlendFinalPeel(renWin);
620 }
621
622 this->Framebuffer->RestorePreviousBindingsAndBuffers();
623
624
625 // Restore the original viewport and scissor test settings
626 this->State->vtkglViewport(this->ViewportX, this->ViewportY,
627 this->ViewportWidth, this->ViewportHeight);
628 if (saveScissorTestState)
629 {
630 this->State->vtkglEnable(GL_SCISSOR_TEST);
631 }
632 else
633 {
634 this->State->vtkglDisable(GL_SCISSOR_TEST);
635 }
636
637 //blit if we drew something
638 if (this->PeelCount > 1 || this->ColorDrawCount != 0)
639 {
640 this->Framebuffer->SaveCurrentBindingsAndBuffers(
641 this->Framebuffer->GetReadMode());
642 this->Framebuffer->Bind(
643 this->Framebuffer->GetReadMode());
644
645 glBlitFramebuffer(
646 0, 0,
647 this->ViewportWidth, this->ViewportHeight,
648 this->ViewportX, this->ViewportY,
649 this->ViewportX + this->ViewportWidth,
650 this->ViewportY + this->ViewportHeight,
651 GL_COLOR_BUFFER_BIT,
652 GL_LINEAR);
653
654 this->Framebuffer->RestorePreviousBindingsAndBuffers(
655 this->Framebuffer->GetReadMode());
656 }
657
658 #ifdef GL_MULTISAMPLE
659 if(multiSampleStatus)
660 {
661 this->State->vtkglEnable(GL_MULTISAMPLE);
662 }
663 #endif
664
665 // unload the textures
666 this->OpaqueZTexture->Deactivate();
667 this->OpaqueRGBATexture->Deactivate();
668 this->TranslucentRGBATexture[0]->Deactivate();
669 this->TranslucentRGBATexture[1]->Deactivate();
670 this->TranslucentRGBATexture[2]->Deactivate();
671 this->TranslucentZTexture[0]->Deactivate();
672 this->TranslucentZTexture[1]->Deactivate();
673
674 // restore blending
675 this->State->vtkglEnable(GL_BLEND);
676
677 this->PostRender(s);
678 for (int j = 0; j < numProps; ++j)
679 {
680 vtkProp *prop = s->GetPropArray()[j];
681 vtkInformation *info = prop->GetPropertyKeys();
682 if (info)
683 {
684 info->Remove(vtkOpenGLActor::GLDepthMaskOverride());
685 }
686 }
687
688 this->NumberOfRenderedProps = this->TranslucentPass->GetNumberOfRenderedProps();
689
690 vtkOpenGLCheckErrorMacro("failed after Render");
691 }
692
693 //------------------------------------------------------------------------------
PostReplaceShaderValues(std::string &,std::string &,std::string & fragmentShader,vtkAbstractMapper *,vtkProp *)694 bool vtkDepthPeelingPass::PostReplaceShaderValues(std::string &,
695 std::string &,
696 std::string &fragmentShader,
697 vtkAbstractMapper *,
698 vtkProp *)
699 {
700 vtkShaderProgram::Substitute(
701 fragmentShader, "//VTK::DepthPeeling::Dec",
702 "uniform vec2 vpSize;\n"
703 "uniform sampler2D opaqueZTexture;\n"
704 "uniform sampler2D translucentZTexture;\n"
705 );
706
707 // Set gl_FragDepth if it isn't set already. It may have already been replaced
708 // by the mapper, in which case the substitution will fail and the previously
709 // set depth value will be used.
710 vtkShaderProgram::Substitute(
711 fragmentShader, "//VTK::Depth::Impl",
712 "gl_FragDepth = gl_FragCoord.z;");
713
714 // the .0000001 below is an epsilon. It turns out that
715 // graphics cards can render the same polygon two times
716 // in a row with different z values. I suspect it has to
717 // do with how rasterization of the polygon is broken up.
718 // A different breakup across fragment shaders can result in
719 // very slightly different z values for some of the pixels.
720 // The end result is that with depth peeling, you can end up
721 // counting/accumulating pixels of the same surface twice
722 // simply due to this randomness in z values. So we introduce
723 // an epsilon into the transparent test to require some
724 // minimal z separation between pixels
725 vtkShaderProgram::Substitute(
726 fragmentShader, "//VTK::DepthPeeling::Impl",
727 "vec2 dpTexCoord = gl_FragCoord.xy / vpSize;\n"
728 " float odepth = texture2D(opaqueZTexture, dpTexCoord).r;\n"
729 " if (gl_FragDepth >= odepth) { discard; }\n"
730 " float tdepth = texture2D(translucentZTexture, dpTexCoord).r;\n"
731 " if (gl_FragDepth <= tdepth + .0000001) { discard; }\n"
732 );
733
734 return true;
735 }
736
737 //------------------------------------------------------------------------------
SetShaderParameters(vtkShaderProgram * program,vtkAbstractMapper *,vtkProp *,vtkOpenGLVertexArrayObject * vtkNotUsed (VAO))738 bool vtkDepthPeelingPass::SetShaderParameters(vtkShaderProgram *program,
739 vtkAbstractMapper*, vtkProp*,
740 vtkOpenGLVertexArrayObject* vtkNotUsed(VAO))
741 {
742 program->SetUniformi("opaqueZTexture",
743 this->OpaqueZTexture->GetTextureUnit());
744 program->SetUniformi("translucentZTexture",
745 this->TranslucentZTexture[(this->PeelCount + 1) % 2]->GetTextureUnit());
746
747 float vpSize[2] = { static_cast<float>(this->ViewportWidth),
748 static_cast<float>(this->ViewportHeight) };
749 program->SetUniform2f("vpSize", vpSize);
750
751 return true;
752 }
753