vtkDepthPeelingPass.cxx 18.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*=========================================================================

Program:   Visualization Toolkit
Module:    vtkDepthPeelingPass.cxx

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkDepthPeelingPass.h"
#include "vtkInformation.h"
#include "vtkObjectFactory.h"
David C. Lonie's avatar
David C. Lonie committed
19
#include "vtkOpenGLActor.h"
20
21
22
23
24
25
26
27
28
29
30
31
#include "vtkOpenGLError.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLShaderCache.h"
#include "vtkProp.h"
#include "vtkRenderState.h"
#include "vtkRenderer.h"
#include "vtkShaderProgram.h"
#include "vtkTextureObject.h"
#include <cassert>
#include <list>

Ken Martin's avatar
Ken Martin committed
32
#include "vtkOpenGLHelper.h"
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

// the 2D blending shaders we use
#include "vtkDepthPeelingPassIntermediateFS.h"
#include "vtkDepthPeelingPassFinalFS.h"
#include "vtkTextureObjectVS.h"

vtkStandardNewMacro(vtkDepthPeelingPass);
vtkCxxSetObjectMacro(vtkDepthPeelingPass,TranslucentPass,vtkRenderPass);

// ----------------------------------------------------------------------------
vtkDepthPeelingPass::vtkDepthPeelingPass()
{
  this->TranslucentPass=0;
  this->IsSupported=false;

  this->OcclusionRatio=0.0;
  this->MaximumNumberOfPeels=4;
  this->DepthPeelingHigherLayer=0;

  this->IntermediateBlendProgram = 0;
  this->FinalBlendProgram = 0;

  this->DepthZData = 0;
  this->OpaqueZTexture = NULL;
  this->TranslucentZTexture = NULL;
  this->OpaqueRGBATexture = NULL;
  this->TranslucentRGBATexture = NULL;
  this->CurrentRGBATexture = NULL;
Ken Martin's avatar
Ken Martin committed
61
62
63
64
65
66

  this->ViewportX = 0;
  this->ViewportY = 0;
  this->ViewportWidth = 100;
  this->ViewportHeight = 100;

67
68
69
70
71
72
}

// ----------------------------------------------------------------------------
vtkDepthPeelingPass::~vtkDepthPeelingPass()
{
  if(this->TranslucentPass!=0)
73
  {
74
    this->TranslucentPass->Delete();
75
  }
76
  delete this->DepthZData;
77
  if (this->OpaqueZTexture)
78
  {
79
80
    this->OpaqueZTexture->UnRegister(this);
    this->OpaqueZTexture = NULL;
81
  }
82
  if (this->TranslucentZTexture)
83
  {
84
85
    this->TranslucentZTexture->UnRegister(this);
    this->TranslucentZTexture = NULL;
86
  }
87
  if (this->OpaqueRGBATexture)
88
  {
89
90
    this->OpaqueRGBATexture->UnRegister(this);
    this->OpaqueRGBATexture = NULL;
91
  }
92
  if (this->TranslucentRGBATexture)
93
  {
94
95
    this->TranslucentRGBATexture->UnRegister(this);
    this->TranslucentRGBATexture = NULL;
96
  }
97
  if (this->CurrentRGBATexture)
98
  {
99
100
    this->CurrentRGBATexture->UnRegister(this);
    this->CurrentRGBATexture = NULL;
101
  }
102
103
104
105
106
107
108
109
110
111
}

//-----------------------------------------------------------------------------
// Description:
// Destructor. Delete SourceCode if any.
void vtkDepthPeelingPass::ReleaseGraphicsResources(vtkWindow *w)
{
  assert("pre: w_exists" && w!=0);

  if (this->FinalBlendProgram !=0)
112
  {
113
114
115
    this->FinalBlendProgram->ReleaseGraphicsResources(w);
    delete this->FinalBlendProgram;
    this->FinalBlendProgram = 0;
116
  }
117
  if (this->IntermediateBlendProgram !=0)
118
  {
119
120
121
    this->IntermediateBlendProgram->ReleaseGraphicsResources(w);
    delete this->IntermediateBlendProgram;
    this->IntermediateBlendProgram = 0;
122
  }
123
  if(this->TranslucentPass)
124
  {
125
    this->TranslucentPass->ReleaseGraphicsResources(w);
126
  }
127
  if (this->OpaqueZTexture)
128
  {
129
    this->OpaqueZTexture->ReleaseGraphicsResources(w);
130
  }
131
  if (this->TranslucentZTexture)
132
  {
133
    this->TranslucentZTexture->ReleaseGraphicsResources(w);
134
  }
135
  if (this->OpaqueRGBATexture)
136
  {
137
    this->OpaqueRGBATexture->ReleaseGraphicsResources(w);
138
  }
139
  if (this->TranslucentRGBATexture)
140
  {
141
    this->TranslucentRGBATexture->ReleaseGraphicsResources(w);
142
  }
143
  if (this->CurrentRGBATexture)
144
  {
145
    this->CurrentRGBATexture->ReleaseGraphicsResources(w);
146
  }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
}

// ----------------------------------------------------------------------------
void vtkDepthPeelingPass::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "OcclusionRation: " << this->OcclusionRatio << endl;

  os << indent << "MaximumNumberOfPeels: " << this->MaximumNumberOfPeels
     << endl;

  os << indent << "TranslucentPass:";
  if(this->TranslucentPass!=0)
161
  {
162
    this->TranslucentPass->PrintSelf(os,indent);
163
  }
164
  else
165
  {
166
    os << "(none)" <<endl;
167
  }
168
169
170
171
172
173
174
175
176
177
}

vtkTextureObject *vtkDepthPeelingPassCreateTextureObject(
  vtkOpenGLRenderWindow *context, int width, int height,
  int numComponents, bool isDepth, void *initialData)
{
  vtkTextureObject *result = vtkTextureObject::New();
  result->SetContext(context);

  if (isDepth == true)
178
  {
179
    if (initialData)
180
    {
181
182
      result->CreateDepthFromRaw(
          width, height, vtkTextureObject::Float32, VTK_FLOAT, initialData);
183
    }
184
    else
185
    {
186
187
      result->AllocateDepth(width, height, vtkTextureObject::Float32);
    }
188
  }
189
  else
190
  {
191
    result->Allocate2D(width, height, numComponents, VTK_UNSIGNED_CHAR);
192
  }
193
194
195
196
197
198
199
200
201

  result->SetMinificationFilter(vtkTextureObject::Nearest);
  result->SetMagnificationFilter(vtkTextureObject::Nearest);
  result->SetWrapS(vtkTextureObject::ClampToEdge);
  result->SetWrapT(vtkTextureObject::ClampToEdge);
  result->SetWrapR(vtkTextureObject::ClampToEdge);
  return result;
}

202
203
204
void vtkDepthPeelingPass::BlendIntermediatePeels(
  vtkOpenGLRenderWindow *renWin,
  bool done)
205
206
207
208
209
210
211
{
  this->CurrentRGBATexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
    this->ViewportX, this->ViewportY,
    this->ViewportWidth, this->ViewportHeight);

  // take the TranslucentRGBA texture and blend it with the current frame buffer
  if (!this->IntermediateBlendProgram)
212
  {
Ken Martin's avatar
Ken Martin committed
213
    this->IntermediateBlendProgram = new vtkOpenGLHelper;
214
215
216
217
    std::string VSSource = vtkTextureObjectVS;
    std::string FSSource = vtkDepthPeelingPassIntermediateFS;
    std::string GSSource;
    this->IntermediateBlendProgram->Program =
218
219
220
221
      renWin->GetShaderCache()->ReadyShaderProgram(
        VSSource.c_str(),
        FSSource.c_str(),
        GSSource.c_str());
222
  }
223
  else
224
  {
225
226
    renWin->GetShaderCache()->ReadyShaderProgram(
      this->IntermediateBlendProgram->Program);
227
  }
228
229
230
231
  this->IntermediateBlendProgram->Program->SetUniformi(
    "translucentRGBATexture", this->TranslucentRGBATexture->GetTextureUnit());
  this->IntermediateBlendProgram->Program->SetUniformi(
    "currentRGBATexture", this->CurrentRGBATexture->GetTextureUnit());
232
233
  this->IntermediateBlendProgram->Program->SetUniformi(
    "lastpass", done ? 1 : 0);
234
235
236
237
238
239

  glDisable(GL_DEPTH_TEST);
  this->CurrentRGBATexture->CopyToFrameBuffer(0, 0,
         this->ViewportWidth-1, this->ViewportHeight-1,
         0, 0, this->ViewportWidth, this->ViewportHeight,
         this->IntermediateBlendProgram->Program,
Ken Martin's avatar
Ken Martin committed
240
         this->IntermediateBlendProgram->VAO);
241
242
243
244
245
246
}


void vtkDepthPeelingPass::BlendFinalPeel(vtkOpenGLRenderWindow *renWin)
{
  if (!this->FinalBlendProgram)
247
  {
Ken Martin's avatar
Ken Martin committed
248
    this->FinalBlendProgram = new vtkOpenGLHelper;
249
250
251
252
    std::string VSSource = vtkTextureObjectVS;
    std::string FSSource = vtkDepthPeelingPassFinalFS;
    std::string GSSource;
    this->FinalBlendProgram->Program =
253
254
255
256
      renWin->GetShaderCache()->ReadyShaderProgram(
        VSSource.c_str(),
        FSSource.c_str(),
        GSSource.c_str());
257
  }
258
  else
259
  {
260
261
    renWin->GetShaderCache()->ReadyShaderProgram(
      this->FinalBlendProgram->Program);
262
  }
263
264
265
266
267
268
269
270

  this->FinalBlendProgram->Program->SetUniformi(
    "translucentRGBATexture", this->TranslucentRGBATexture->GetTextureUnit());

  this->OpaqueRGBATexture->Activate();
  this->FinalBlendProgram->Program->SetUniformi(
    "opaqueRGBATexture", this->OpaqueRGBATexture->GetTextureUnit());

271
272
273
274
  this->OpaqueZTexture->Activate();
  this->FinalBlendProgram->Program->SetUniformi(
    "opaqueZTexture", this->OpaqueZTexture->GetTextureUnit());

275
  // blend in OpaqueRGBA
276
277
  glEnable(GL_DEPTH_TEST);
  glDepthFunc( GL_ALWAYS );
278
279
280
281
  this->OpaqueRGBATexture->CopyToFrameBuffer(0, 0,
         this->ViewportWidth-1, this->ViewportHeight-1,
         0, 0, this->ViewportWidth, this->ViewportHeight,
         this->FinalBlendProgram->Program,
Ken Martin's avatar
Ken Martin committed
282
         this->FinalBlendProgram->VAO);
283
  glDepthFunc( GL_LEQUAL );
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
}



// ----------------------------------------------------------------------------
// Description:
// Perform rendering according to a render state \p s.
// \pre s_exists: s!=0
void vtkDepthPeelingPass::Render(const vtkRenderState *s)
{
  assert("pre: s_exists" && s!=0);

  this->NumberOfRenderedProps=0;

  if(this->TranslucentPass==0)
299
  {
300
301
    vtkWarningMacro(<<"No TranslucentPass delegate set. Nothing can be rendered.");
    return;
302
  }
303
304
305
306
307

  // Any prop to render?
  bool hasTranslucentPolygonalGeometry=false;
  int i=0;
  while(!hasTranslucentPolygonalGeometry && i<s->GetPropArrayCount())
308
  {
309
310
311
    hasTranslucentPolygonalGeometry=
      s->GetPropArray()[i]->HasTranslucentPolygonalGeometry()==1;
    ++i;
312
  }
313
  if(!hasTranslucentPolygonalGeometry)
314
  {
315
    return; // nothing to render.
316
  }
317

318
319
320
321
  // check driver support
  vtkOpenGLRenderWindow *renWin
    = vtkOpenGLRenderWindow::SafeDownCast(s->GetRenderer()->GetRenderWindow());

322
  // we need alpha planes
323
324
  int rgba[4];
  renWin->GetColorBufferSizes(rgba);
325

326
  if (rgba[3] < 8)
327
  {
328
329
330
    // just use alpha blending
    this->TranslucentPass->Render(s);
    return;
331
  }
332

333
334
335
336
  // Depth peeling.
  vtkRenderer *r=s->GetRenderer();

  if(s->GetFrameBuffer()==0)
337
  {
338
339
340
    // get the viewport dimensions
    r->GetTiledSizeAndOrigin(&this->ViewportWidth,&this->ViewportHeight,
                             &this->ViewportX,&this->ViewportY);
341
  }
342
  else
343
  {
344
345
346
347
348
349
    int size[2];
    s->GetWindowSize(size);
    this->ViewportWidth=size[0];
    this->ViewportHeight=size[1];
    this->ViewportX=0;
    this->ViewportY=0;
350
  }
351
352
353
354
355

  // has the size changed?
  if (this->OpaqueRGBATexture && (
      this->OpaqueRGBATexture->GetWidth() != static_cast<unsigned int>(this->ViewportWidth) ||
      this->OpaqueRGBATexture->GetHeight() != static_cast<unsigned int>(this->ViewportHeight)))
356
  {
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    delete this->DepthZData;
    this->DepthZData = 0;

    this->OpaqueZTexture->UnRegister(this);
    this->OpaqueZTexture = 0;

    this->OpaqueRGBATexture->UnRegister(this);
    this->OpaqueRGBATexture = 0;

    this->TranslucentRGBATexture->UnRegister(this);
    this->TranslucentRGBATexture = 0;

    this->CurrentRGBATexture->UnRegister(this);
    this->CurrentRGBATexture = 0;
371
  }
372
373

  // create textures we need if not done already
Ken Martin's avatar
Ken Martin committed
374
  if (this->OpaqueRGBATexture == NULL)
375
  {
376
377
378
379
380
381
382
383
384
    this->OpaqueZTexture = vtkDepthPeelingPassCreateTextureObject(
      renWin, this->ViewportWidth, this->ViewportHeight, 1, true, NULL);
    this->OpaqueRGBATexture = vtkDepthPeelingPassCreateTextureObject(
      renWin, this->ViewportWidth, this->ViewportHeight, 4, false, NULL);
    this->TranslucentRGBATexture = vtkDepthPeelingPassCreateTextureObject(
      renWin, this->ViewportWidth, this->ViewportHeight, 4, false, NULL);
    this->CurrentRGBATexture = vtkDepthPeelingPassCreateTextureObject(
      renWin, this->ViewportWidth, this->ViewportHeight, 4, false, NULL);
    this->DepthZData = new std::vector<float>(this->ViewportWidth * this->ViewportHeight, 0.0);
385
  }
386
387
388
389
390

  this->TranslucentZTexture = vtkDepthPeelingPassCreateTextureObject(
    renWin, this->ViewportWidth, this->ViewportHeight, 1, true, &((*this->DepthZData)[0]));

  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
391
  glClearColor(0.0,0.0,0.0,0.0); // always clear to black
392
393
 // glClearDepth(static_cast<GLclampf>(1.0));
#ifdef GL_MULTISAMPLE
394
  GLboolean multiSampleStatus = glIsEnabled(GL_MULTISAMPLE);
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
  glDisable(GL_MULTISAMPLE);
#endif
  glDisable(GL_BLEND);

  // Get opaqueRGBA and opaqueZ
  this->OpaqueRGBATexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
    this->ViewportX, this->ViewportY,
    this->ViewportWidth, this->ViewportHeight);
  this->OpaqueRGBATexture->Deactivate(); // deactivate & unbind to save texture resources
  this->OpaqueZTexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
    this->ViewportX, this->ViewportY,
    this->ViewportWidth, this->ViewportHeight);

  this->TranslucentZTexture->Activate();
  this->OpaqueZTexture->Activate();

David C. Lonie's avatar
David C. Lonie committed
411
412
  // Setup property keys for actors:
  this->PreRender(s);
413

David C. Lonie's avatar
David C. Lonie committed
414
415
416
417
  // Enable the depth buffer (otherwise it's disabled for translucent geometry)
  assert("Render state valid." && s);
  int numProps = s->GetPropArrayCount();
  for (int j = 0; j < numProps; ++j)
418
  {
David C. Lonie's avatar
David C. Lonie committed
419
420
    vtkProp *prop = s->GetPropArray()[j];
    vtkInformation *info = prop->GetPropertyKeys();
421
    if (!info)
422
    {
423
      info = vtkInformation::New();
David C. Lonie's avatar
David C. Lonie committed
424
425
      prop->SetPropertyKeys(info);
      info->FastDelete();
426
    }
427
428
    info->Set(vtkOpenGLActor::GLDepthMaskOverride(), 1);
  }
429
430
431
432
433

  // Do render loop until complete
  unsigned int threshold=
    static_cast<unsigned int>(this->ViewportWidth*this->ViewportHeight*OcclusionRatio);

Ken Martin's avatar
Ken Martin committed
434
#if GL_ES_VERSION_3_0 != 1
435
436
437
438
439
  GLuint queryId;
  glGenQueries(1,&queryId);
#endif

  bool done = false;
440
  GLuint nbPixels = threshold + 1;
441
  int peelCount = 0;
442
  glDepthFunc( GL_LEQUAL );
443
  while(!done)
444
  {
445
446
447
448
449
450
451
    glDepthMask(GL_TRUE);
    glEnable(GL_DEPTH_TEST);

    // clear the zbuffer and color buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // render the translucent geometry
Ken Martin's avatar
Ken Martin committed
452
#if GL_ES_VERSION_3_0 != 1
453
454
455
    glBeginQuery(GL_SAMPLES_PASSED,queryId);
#endif

456
457
458
459
460
    // check if we are going to exceed the max number of peels or if we
    // exceeded the pixel threshold last time
    peelCount++;
    if ((this->MaximumNumberOfPeels && peelCount >= this->MaximumNumberOfPeels) ||
       nbPixels <= threshold)
461
    {
462
463
464
465
466
      done = true;
      // if so we do this last render using alpha blending for all
      // the stuff that is left
      glEnable(GL_BLEND);
      glDepthFunc( GL_ALWAYS );
467
    }
468
    this->TranslucentPass->Render(s);
469
470
    glDepthFunc( GL_LEQUAL );
    glDisable(GL_BLEND);
471

Ken Martin's avatar
Ken Martin committed
472
#if GL_ES_VERSION_3_0 != 1
473
474
475
    glEndQuery(GL_SAMPLES_PASSED);
    glGetQueryObjectuiv(queryId,GL_QUERY_RESULT,&nbPixels);
#endif
476
    // cerr << "Pass " << peelCount << " pixels Drawn " << nbPixels << "\n";
477
478
479

    // if something was drawn, blend it in
    if (nbPixels > 0)
480
    {
481
482
483
484
485
486
487
488
      // update translucentZ
      this->TranslucentZTexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
          this->ViewportX, this->ViewportY,
          this->ViewportWidth, this->ViewportHeight);


      // blend the last two peels together
      if (peelCount > 1)
489
      {
490
        this->BlendIntermediatePeels(renWin,done);
491
      }
492

493
494
495
496
      // update translucent RGBA
      this->TranslucentRGBATexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
        this->ViewportX, this->ViewportY,
        this->ViewportWidth, this->ViewportHeight);
497
    }
498
    else // if we drew nothing we are done
499
    {
500
501
502
      // if we drew nothing on the very first frame we still
      // need a valid texture to blend with so copy it
      if (peelCount == 1)
503
      {
504
505
506
        this->TranslucentRGBATexture->CopyFromFrameBuffer(this->ViewportX, this->ViewportY,
          this->ViewportX, this->ViewportY,
          this->ViewportWidth, this->ViewportHeight);
507
      }
508
      done = true;
509
    }
510
  }
511

David C. Lonie's avatar
David C. Lonie committed
512
513
//  std::cout << "Number of peels: " << peelCount << "\n";

514
515
516
517
518
519
520
521
  // unload the textures we are done with
  this->CurrentRGBATexture->Deactivate();
  this->TranslucentZTexture->UnRegister(this);
  this->TranslucentZTexture = 0;

  // do the final blend
  this->BlendFinalPeel(renWin);

522
523
#ifdef GL_MULTISAMPLE
   if(multiSampleStatus)
524
   {
525
      glEnable(GL_MULTISAMPLE);
526
   }
527
528
#endif

529
  this->OpaqueZTexture->Deactivate();
530
531
532
533
  // unload the last two textures
  this->TranslucentRGBATexture->Deactivate();
  this->OpaqueRGBATexture->Deactivate();

534
535
536
  // restore blending
  glEnable(GL_BLEND);

David C. Lonie's avatar
David C. Lonie committed
537
538
  this->PostRender(s);
  for (int j = 0; j < numProps; ++j)
539
  {
David C. Lonie's avatar
David C. Lonie committed
540
541
542
    vtkProp *prop = s->GetPropArray()[j];
    vtkInformation *info = prop->GetPropertyKeys();
    if (info)
543
    {
David C. Lonie's avatar
David C. Lonie committed
544
      info->Remove(vtkOpenGLActor::GLDepthMaskOverride());
Ken Martin's avatar
Ken Martin committed
545
    }
546
  }
Ken Martin's avatar
Ken Martin committed
547

548
549
550
551
  this->NumberOfRenderedProps = this->TranslucentPass->GetNumberOfRenderedProps();

  vtkOpenGLCheckErrorMacro("failed after Render");
}
David C. Lonie's avatar
David C. Lonie committed
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

//------------------------------------------------------------------------------
bool vtkDepthPeelingPass::ReplaceShaderValues(std::string &,
                                              std::string &,
                                              std::string &fragmentShader,
                                              vtkAbstractMapper *,
                                              vtkProp *)
{
  vtkShaderProgram::Substitute(
        fragmentShader, "//VTK::DepthPeeling::Dec",
        "uniform vec2 screenSize;\n"
        "uniform sampler2D opaqueZTexture;\n"
        "uniform sampler2D translucentZTexture;\n"
        );

567
568
569
570
571
572
573
  // Set gl_FragDepth if it isn't set already. It may have already been replaced
  // by the mapper, in which case the substitution will fail and the previously
  // set depth value will be used.
  vtkShaderProgram::Substitute(
        fragmentShader, "//VTK::Depth::Impl",
        "gl_FragDepth = gl_FragCoord.z;");

David C. Lonie's avatar
David C. Lonie committed
574
575
576
577
578
579
580
581
582
583
584
585
586
587
  // the .0000001 below is an epsilon.  It turns out that
  // graphics cards can render the same polygon two times
  // in a row with different z values. I suspect it has to
  // do with how rasterization of the polygon is broken up.
  // A different breakup across fragment shaders can result in
  // very slightly different z values for some of the pixels.
  // The end result is that with depth peeling, you can end up
  // counting/accumulating pixels of the same surface twice
  // simply due to this randomness in z values. So we introduce
  // an epsilon into the transparent test to require some
  // minimal z seperation between pixels
  vtkShaderProgram::Substitute(
        fragmentShader, "//VTK::DepthPeeling::Impl",
        "float odepth = texture2D(opaqueZTexture, gl_FragCoord.xy/screenSize).r;\n"
588
        "  if (gl_FragDepth >= odepth) { discard; }\n"
David C. Lonie's avatar
David C. Lonie committed
589
        "  float tdepth = texture2D(translucentZTexture, gl_FragCoord.xy/screenSize).r;\n"
590
        "  if (gl_FragDepth <= tdepth + .0000001) { discard; }\n"
David C. Lonie's avatar
David C. Lonie committed
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
        );

  return true;
}

//------------------------------------------------------------------------------
bool vtkDepthPeelingPass::SetShaderParameters(vtkShaderProgram *program,
                                              vtkAbstractMapper*, vtkProp*)
{
  program->SetUniformi("opaqueZTexture",
                       this->OpaqueZTexture->GetTextureUnit());
  program->SetUniformi("translucentZTexture",
                       this->TranslucentZTexture->GetTextureUnit());

  float screenSize[2] = { static_cast<float>(this->ViewportWidth),
                          static_cast<float>(this->ViewportHeight) };
  program->SetUniform2f("screenSize", screenSize);

  return true;
}