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