1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkOpenGLRenderer.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 #include "vtkOpenGLRenderer.h"
16
17 #include "vtkCuller.h"
18 #include "vtkLightCollection.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkOpenGLCamera.h"
21 #include "vtkOpenGLLight.h"
22 #include "vtkOpenGLProperty.h"
23 #include "vtkRenderWindow.h"
24 #include "vtkOpenGLRenderWindow.h"
25 #include "vtkOpenGLExtensionManager.h"
26 #include "vtkgl.h" // vtkgl namespace
27 #include "vtkImageImport.h"
28 #include "vtkPNGWriter.h"
29 #include "vtkOpenGLTexture.h"
30 #include "vtkTimerLog.h"
31 #include "vtkRenderPass.h"
32 #include "vtkRenderState.h"
33
34 #include "vtkOpenGL.h"
35 #include "vtkOpenGLError.h"
36
37 #include "vtkShaderProgram2.h"
38
39 #include <math.h>
40 #include <cassert>
41 #include <list>
42
43 class vtkGLPickInfo
44 {
45 public:
46 GLuint* PickBuffer;
47 GLuint PickedId;
48 GLuint NumPicked;
49 };
50
51 vtkStandardNewMacro(vtkOpenGLRenderer);
52
53 vtkCxxSetObjectMacro(vtkOpenGLRenderer,ShaderProgram,vtkShaderProgram2);
54 vtkCxxSetObjectMacro(vtkOpenGLRenderer, Pass, vtkRenderPass);
55
56 #define VTK_MAX_LIGHTS 8
57
58 // List of rgba layers, id are 2D rectangle texture Ids.
59 class vtkOpenGLRendererLayerList
60 {
61 public:
62 std::list<GLuint> List;
63 };
64
65 extern const char *vtkOpenGLRenderer_PeelingFS;
66
vtkOpenGLRenderer()67 vtkOpenGLRenderer::vtkOpenGLRenderer()
68 {
69 this->PickInfo = new vtkGLPickInfo;
70 this->NumberOfLightsBound = 0;
71 this->PickInfo->PickBuffer = 0;
72 this->PickInfo->PickedId = 0;
73 this->PickInfo->NumPicked = 0;
74 this->PickedZ = 0;
75
76 this->DepthPeelingIsSupported=0;
77 this->DepthPeelingIsSupportedChecked=0;
78 this->LayerList=0;
79 this->OpaqueLayerZ=0;
80 this->TransparentLayerZ=0;
81 this->ProgramShader=0;
82 this->DepthFormat=0;
83 this->DepthPeelingHigherLayer=0;
84
85 this->ShaderProgram=0;
86 this->BackgroundTexture = 0;
87 this->Pass = 0;
88 }
89
90 // Internal method temporarily removes lights before reloading them
91 // into graphics pipeline.
ClearLights(void)92 void vtkOpenGLRenderer::ClearLights (void)
93 {
94 vtkOpenGLClearErrorMacro();
95
96 short curLight;
97 float Info[4];
98
99 // define a lighting model and set up the ambient light.
100 // use index 11 for the heck of it. Doesn't matter except for 0.
101
102 // update the ambient light
103 Info[0] = this->Ambient[0];
104 Info[1] = this->Ambient[1];
105 Info[2] = this->Ambient[2];
106 Info[3] = 1.0;
107 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Info);
108
109 if ( this->TwoSidedLighting )
110 {
111 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
112 }
113 else
114 {
115 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
116 }
117
118 // now delete all the old lights
119 for (curLight = GL_LIGHT0; curLight < GL_LIGHT0 + VTK_MAX_LIGHTS; curLight++)
120 {
121 glDisable(static_cast<GLenum>(curLight));
122 }
123
124 this->NumberOfLightsBound = 0;
125
126 vtkOpenGLCheckErrorMacro("failed ater ClearLights");
127 }
128
129 // Ask lights to load themselves into graphics pipeline.
UpdateLights()130 int vtkOpenGLRenderer::UpdateLights ()
131 {
132 vtkOpenGLClearErrorMacro();
133
134 vtkLight *light;
135 short curLight;
136 float status;
137 int count;
138
139 // Check if a light is on. If not then make a new light.
140 count = 0;
141 curLight= this->NumberOfLightsBound + GL_LIGHT0;
142
143 vtkCollectionSimpleIterator sit;
144 for(this->Lights->InitTraversal(sit);
145 (light = this->Lights->GetNextLight(sit)); )
146 {
147 status = light->GetSwitch();
148 if ((status > 0.0)&& (curLight < (GL_LIGHT0+VTK_MAX_LIGHTS)))
149 {
150 curLight++;
151 count++;
152 }
153 }
154
155 if( !count )
156 {
157 vtkDebugMacro(<<"No lights are on, creating one.");
158 this->CreateLight();
159 }
160
161 count = 0;
162 curLight= this->NumberOfLightsBound + GL_LIGHT0;
163
164 // set the matrix mode for lighting. ident matrix on viewing stack
165 glMatrixMode(GL_MODELVIEW);
166 glPushMatrix();
167
168 for(this->Lights->InitTraversal(sit);
169 (light = this->Lights->GetNextLight(sit)); )
170 {
171
172 status = light->GetSwitch();
173
174 // if the light is on then define it and bind it.
175 // also make sure we still have room.
176 if ((status > 0.0)&& (curLight < (GL_LIGHT0+VTK_MAX_LIGHTS)))
177 {
178 light->Render(this,curLight);
179 glEnable(static_cast<GLenum>(curLight));
180
181 // increment the current light by one
182 curLight++;
183 count++;
184 }
185 }
186
187 this->NumberOfLightsBound = curLight - GL_LIGHT0;
188
189 glPopMatrix();
190 glEnable(GL_LIGHTING);
191
192 vtkOpenGLCheckErrorMacro("failed after UpdateLights");
193
194 return count;
195 }
196
197 // ----------------------------------------------------------------------------
198 // Description:
199 // Access to the OpenGL program shader uniform variable "useTexture" from the
200 // vtkOpenGLProperty or vtkOpenGLTexture.
GetUseTextureUniformVariable()201 int vtkOpenGLRenderer::GetUseTextureUniformVariable()
202 {
203 GLint result=vtkgl::GetUniformLocation(this->ProgramShader,"useTexture");
204 vtkOpenGLCheckErrorMacro("failed at glGetUniformLocation");
205 if(result==-1)
206 {
207 vtkErrorMacro(<<"useTexture is not a uniform variable");
208 }
209 return result;
210 }
211
212 // ----------------------------------------------------------------------------
213 // Description:
214 // Access to the OpenGL program shader uniform variable "texture" from the
215 // vtkOpenGLProperty or vtkOpenGLTexture.
GetTextureUniformVariable()216 int vtkOpenGLRenderer::GetTextureUniformVariable()
217 {
218 GLint result=vtkgl::GetUniformLocation(this->ProgramShader,"texture");
219 vtkOpenGLCheckErrorMacro("failed at glGetUniformLocation");
220 if(result==-1)
221 {
222 vtkErrorMacro(<<"texture is not a uniform variable");
223 }
224 return result;
225 }
226
227 // ----------------------------------------------------------------------------
228 // Description:
229 // Is rendering at translucent geometry stage using depth peeling and
230 // rendering a layer other than the first one? (Boolean value)
231 // If so, the uniform variables UseTexture and Texture can be set.
232 // (Used by vtkOpenGLProperty or vtkOpenGLTexture)
GetDepthPeelingHigherLayer()233 int vtkOpenGLRenderer::GetDepthPeelingHigherLayer()
234 {
235 return this->DepthPeelingHigherLayer;
236 }
237
238 // ----------------------------------------------------------------------------
239 // Concrete open gl render method.
DeviceRender(void)240 void vtkOpenGLRenderer::DeviceRender(void)
241 {
242 vtkTimerLog::MarkStartEvent("OpenGL Dev Render");
243
244 if(this->Pass!=0)
245 {
246 vtkRenderState s(this);
247 s.SetPropArrayAndCount(this->PropArray, this->PropArrayCount);
248 s.SetFrameBuffer(0);
249 this->Pass->Render(&s);
250 }
251 else
252 {
253 // Do not remove this MakeCurrent! Due to Start / End methods on
254 // some objects which get executed during a pipeline update,
255 // other windows might get rendered since the last time
256 // a MakeCurrent was called.
257 this->RenderWindow->MakeCurrent();
258 vtkOpenGLClearErrorMacro();
259
260 // standard render method
261 this->ClearLights();
262
263 this->UpdateCamera();
264 this->UpdateLightGeometry();
265 this->UpdateLights();
266
267 // set matrix mode for actors
268 glMatrixMode(GL_MODELVIEW);
269
270 this->UpdateGeometry();
271
272 // clean up the model view matrix set up by the camera
273 glMatrixMode(GL_MODELVIEW);
274
275 GLint mvDepth;
276 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepth);
277 if (mvDepth>1)
278 {
279 glPopMatrix();
280 }
281
282 vtkOpenGLCheckErrorMacro("failed after DeviceRender");
283 }
284
285 vtkTimerLog::MarkEndEvent("OpenGL Dev Render");
286 }
287
288 // ----------------------------------------------------------------------------
289 // Description:
290 // Render translucent polygonal geometry. Default implementation just call
291 // UpdateTranslucentPolygonalGeometry().
292 // Subclasses of vtkRenderer that can deal with depth peeling must
293 // override this method.
DeviceRenderTranslucentPolygonalGeometry()294 void vtkOpenGLRenderer::DeviceRenderTranslucentPolygonalGeometry()
295 {
296 vtkOpenGLClearErrorMacro();
297
298 vtkOpenGLExtensionManager *extensions = NULL;
299
300 if(this->UseDepthPeeling)
301 {
302 vtkOpenGLRenderWindow *context
303 = vtkOpenGLRenderWindow::SafeDownCast(this->RenderWindow);
304 if (!context)
305 {
306 vtkErrorMacro("OpenGL render window is required.")
307 return;
308 }
309 extensions = context->GetExtensionManager();
310
311 if(!this->DepthPeelingIsSupportedChecked)
312 {
313 this->DepthPeelingIsSupportedChecked=1;
314
315 int supports_GL_1_3=extensions->ExtensionSupported("GL_VERSION_1_3");
316 int supports_GL_1_4=extensions->ExtensionSupported("GL_VERSION_1_4");
317 int supports_GL_1_5=extensions->ExtensionSupported("GL_VERSION_1_5");
318 int supports_GL_2_0=extensions->ExtensionSupported("GL_VERSION_2_0");
319
320 int supports_vertex_shader;
321 int supports_fragment_shader;
322 int supports_shader_objects;
323 if(supports_GL_2_0)
324 {
325 supports_vertex_shader=1;
326 supports_fragment_shader=1;
327 supports_shader_objects=1;
328 }
329 else
330 {
331 supports_vertex_shader=extensions->ExtensionSupported("GL_ARB_vertex_shader");
332 supports_fragment_shader=extensions->ExtensionSupported("GL_ARB_fragment_shader");
333 supports_shader_objects=extensions->ExtensionSupported("GL_ARB_shader_objects");
334 }
335 int supports_multitexture=supports_GL_1_3 || extensions->ExtensionSupported("GL_ARB_multitexture");
336 int supports_occlusion_query;
337 int supports_shadow_funcs;
338 if(supports_GL_1_5)
339 {
340 supports_occlusion_query=1;
341 supports_shadow_funcs=1;
342 }
343 else
344 {
345 supports_occlusion_query=extensions->ExtensionSupported("GL_ARB_occlusion_query");
346 supports_shadow_funcs=extensions->ExtensionSupported("GL_EXT_shadow_funcs");
347 }
348
349 int supports_depth_texture;
350 int supports_shadow;
351 int supports_blend_func_separate;
352 if(supports_GL_1_4)
353 {
354 supports_depth_texture=1;
355 supports_blend_func_separate=1;
356 supports_shadow=1;
357 }
358 else
359 {
360 supports_depth_texture=extensions->ExtensionSupported("GL_ARB_depth_texture");
361 supports_shadow=extensions->ExtensionSupported("GL_ARB_shadow");
362 supports_blend_func_separate=extensions->ExtensionSupported("GL_EXT_blend_func_separate");
363 }
364
365 int supports_GL_ARB_texture_rectangle=extensions->ExtensionSupported("GL_ARB_texture_rectangle");
366
367 // spec claims it is GL_SGIS_texture_edge_clamp, reality shows it is
368 // GL_EXT_texture_edge_clamp on Nvidia.
369 // part of OpenGL 1.2 core
370 // there is no new function with this extension, we don't need to load
371 // it.
372 int supports_edge_clamp=extensions->ExtensionSupported("GL_VERSION_1_2");
373 if(!supports_edge_clamp)
374 {
375 supports_edge_clamp=extensions->ExtensionSupported("GL_SGIS_texture_edge_clamp");
376 if(!supports_edge_clamp)
377 {
378 // nvidia cards.
379 supports_edge_clamp=extensions->ExtensionSupported("GL_EXT_texture_edge_clamp");
380 }
381 }
382
383 GLint alphaBits;
384 glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
385 int supportsAtLeast8AlphaBits=alphaBits>=8;
386
387 // Mesa with "Offscreen" renderer (ie OS Mesa) supports depth peeling in
388 // all versions tested 7.10, 8.0, 8.0.5, 9.0.3, 9.1.3, 9.1.4, 9.1.5
389 // Mesa version 7 with "Software Rasterizer" renderer all Opacity/Translucent
390 // ctests fail with depth peeling
391 // Mesa 9.2.0 with Gallium llvmpipe renderer some of these tests fail
392 // Mesa 8 with GMA945 renderer supports depth peeling
393 // ATI Radeon HD XXXXX on Windows chokes on PROXY_TEXTURE_RECTANGLE_ARB
394 // memory querries however if those are not used all the tests pass.
395 // ATI Radeon HD on Mac OSX PROXY_TEXTURE_RECTANGLE_ARB are fine but
396 // TestTranslucentLUTDepthPeeling fails. So leave it disabled on Apple
397 int driver_support
398 = (!(extensions->DriverIsATI()
399 && (extensions->GetDriverGLVersionMajor() < 3))
400 && (!extensions->DriverIsMesa()
401 || extensions->DriverGLRendererHas("Offscreen")
402 || (extensions->DriverVersionAtLeast(6,5,3)
403 && !extensions->DriverGLRendererIs("Software Rasterizer")
404 && !extensions->DriverGLRendererHasToken("llvmpipe"))))
405 || extensions->GetIgnoreDriverBugs("ATI/Mesa depth peeling bug.");
406
407 this->DepthPeelingIsSupported =
408 supports_depth_texture &&
409 supports_shadow &&
410 supports_blend_func_separate &&
411 supports_shadow_funcs &&
412 supports_vertex_shader &&
413 supports_fragment_shader &&
414 supports_shader_objects &&
415 supports_occlusion_query &&
416 supports_multitexture &&
417 supports_GL_ARB_texture_rectangle &&
418 supports_edge_clamp &&
419 supportsAtLeast8AlphaBits &&
420 driver_support;
421
422 if(this->DepthPeelingIsSupported)
423 {
424 vtkDebugMacro("depth peeling supported");
425 if(supports_GL_1_3)
426 {
427 extensions->LoadExtension("GL_VERSION_1_3");
428 }
429 else
430 {
431 extensions->LoadCorePromotedExtension("GL_ARB_multitexture");
432 }
433 // GL_ARB_depth_texture, GL_ARB_shadow and GL_EXT_shadow_funcs
434 // don't introduce new functions.
435 if(supports_GL_1_4)
436 {
437 extensions->LoadExtension("GL_VERSION_1_4");
438 }
439 else
440 {
441 extensions->LoadCorePromotedExtension("GL_EXT_blend_func_separate");
442 }
443
444 if(supports_GL_2_0)
445 {
446 extensions->LoadExtension("GL_VERSION_2_0");
447 }
448 else
449 {
450 extensions->LoadCorePromotedExtension("GL_ARB_vertex_shader");
451 extensions->LoadCorePromotedExtension("GL_ARB_fragment_shader");
452 extensions->LoadCorePromotedExtension("GL_ARB_shader_objects");
453 }
454 if(supports_GL_1_5)
455 {
456 extensions->LoadExtension("GL_VERSION_1_5");
457 }
458 else
459 {
460 extensions->LoadCorePromotedExtension("GL_ARB_occlusion_query");
461 }
462
463 extensions->LoadExtension("GL_ARB_texture_rectangle");
464
465 // Some OpenGL implementations such as Mesa or ATI
466 // claim to support both GLSL and GL_ARB_texture_rectangle but
467 // don't actually support sampler2DRectShadow in a GLSL code.
468 // To test that, we compile the shader, if it fails, we don't use
469 // deph peeling
470 GLuint shader =
471 vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
472 vtkgl::ShaderSource(
473 shader, 1,
474 const_cast<const char **>(&vtkOpenGLRenderer_PeelingFS), 0);
475 vtkgl::CompileShader(shader);
476 GLint params;
477 vtkgl::GetShaderiv(shader,vtkgl::COMPILE_STATUS,
478 ¶ms);
479 this->DepthPeelingIsSupported = params==GL_TRUE;
480 vtkgl::DeleteShader(shader);
481 if(!this->DepthPeelingIsSupported)
482 {
483 vtkDebugMacro("this OpenGL implementation does not support "
484 "GL_ARB_texture_rectangle in GLSL code");
485 }
486 }
487 else
488 {
489 vtkDebugMacro(<<"depth peeling is not supported.");
490 if(!supports_depth_texture)
491 {
492 vtkDebugMacro(<<"neither OpenGL 1.4 nor GL_ARB_depth_texture is supported");
493 }
494 if(!supports_shadow)
495 {
496 vtkDebugMacro(<<"neither OpenGL 1.4 nor GL_ARB_shadow is supported");
497 }
498 if(!supports_shadow_funcs)
499 {
500 vtkDebugMacro(<<"neither OpenGL 1.5 nor GL_EXT_shadow_funcs is supported");
501 }
502 if(!supports_vertex_shader)
503 {
504 vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_vertex_shader is supported");
505 }
506 if(!supports_fragment_shader)
507 {
508 vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_fragment_shader is supported");
509 }
510 if(!supports_shader_objects)
511 {
512 vtkDebugMacro(<<"neither OpenGL 2.0 nor GL_ARB_shader_objects is supported");
513 }
514 if(!supports_occlusion_query)
515 {
516 vtkDebugMacro(<<"neither OpenGL 1.5 nor GL_ARB_occlusion_query is supported");
517 }
518 if(!supports_multitexture)
519 {
520 vtkDebugMacro(<<"neither OpenGL 1.3 nor GL_ARB_multitexture is supported");
521 }
522 if(!supports_GL_ARB_texture_rectangle)
523 {
524 vtkDebugMacro(<<"GL_ARB_texture_rectangle is not supported");
525 }
526 if(!supports_edge_clamp)
527 {
528 vtkDebugMacro(<<"neither OpenGL 1.2 nor GL_SGIS_texture_edge_clamp nor GL_EXT_texture_edge_clamp is not supported");
529 }
530 if(!supportsAtLeast8AlphaBits)
531 {
532 vtkDebugMacro(<<"at least 8 alpha bits is not supported");
533 }
534 if (!driver_support)
535 {
536 vtkDebugMacro(<<"buggy driver (Mesa < 6.5.3 or ATI)");
537 }
538 }
539 }
540 }
541
542 if(!this->UseDepthPeeling || !this->DepthPeelingIsSupported)
543 {
544 // just alpha blending
545 this->LastRenderingUsedDepthPeeling=0;
546 this->UpdateTranslucentPolygonalGeometry();
547 }
548 else
549 {
550 // depth peeling.
551
552 // get the viewport dimensions
553 this->GetTiledSizeAndOrigin(&this->ViewportWidth,&this->ViewportHeight,
554 &this->ViewportX,&this->ViewportY);
555
556 // get z bits
557 GLint depthBits;
558 glGetIntegerv(GL_DEPTH_BITS,&depthBits);
559 if(depthBits==16)
560 {
561 this->DepthFormat=vtkgl::DEPTH_COMPONENT16_ARB;
562 }
563 else
564 {
565 this->DepthFormat=vtkgl::DEPTH_COMPONENT24_ARB;
566 }
567
568 vtkgl::ActiveTexture(vtkgl::TEXTURE1);
569
570 // check if the GPU supports a viewport sized texture in
571 // the formats we will use. If not then we should fallback
572 // to alpha blending.
573
574 // This check is really an anachronism since modern GPU
575 // typically support full screen sized textures in all the
576 // common formats.
577
578 GLint depthTexSupport = 1;
579 GLint colorTexSupport = 1;
580
581 if ( extensions->DriverIsATI()
582 && !extensions->GetIgnoreDriverBugs("ATI proxy query bug.") )
583 {
584 // The ATI Radeon HD drivers currently choke on the proxy
585 // query, but depth peeling has been confirmed to work. For
586 // those driver fall back on the weaker max texture size
587 // check.
588 GLint maxTexSize = 0;
589 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
590 if ( (this->ViewportWidth > maxTexSize)
591 || (this->ViewportHeight > maxTexSize) )
592 {
593 depthTexSupport = 0;
594 colorTexSupport = 0;
595 }
596 }
597 else
598 {
599 // Not a buggy ATI driver, it's OK to make the proxy query.
600 GLuint proxyQueryTex = 0;
601 glGenTextures(1, &proxyQueryTex);
602 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB, proxyQueryTex);
603
604 // support for depth buffer format
605 glTexImage2D(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0, this->DepthFormat,
606 this->ViewportWidth, this->ViewportHeight, 0,
607 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,0);
608
609 glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0,
610 GL_TEXTURE_WIDTH, &depthTexSupport);
611
612 // support for color buffer
613 glTexImage2D(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
614 this->ViewportWidth, this->ViewportHeight, 0, GL_RGBA,
615 GL_UNSIGNED_BYTE, 0);
616
617 glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_RECTANGLE_ARB, 0,
618 GL_TEXTURE_WIDTH,&colorTexSupport);
619
620 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB, 0);
621 glDeleteTextures(1, &proxyQueryTex);
622 }
623
624 if (!(depthTexSupport && colorTexSupport))
625 {
626 // GPU does not support a view sized texture in this format.
627 // Do alpha blending technique instead.
628 vtkWarningMacro(
629 << "The GPU supports "
630 << this->ViewportWidth << "x"
631 << this->ViewportHeight << " texture: depth buffer "
632 << (depthTexSupport?"yes":"no") << ", color buffer "
633 << (colorTexSupport?"yes":"no"));
634
635 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
636 this->LastRenderingUsedDepthPeeling = 0;
637 this->UpdateTranslucentPolygonalGeometry();
638 return;
639 }
640
641 // 1. Grab the RGBAZ of the opaque layer.
642 GLuint opaqueLayerZ=0;
643 GLuint opaqueLayerRgba=0;
644 glGenTextures(1,&opaqueLayerZ);
645 this->OpaqueLayerZ=opaqueLayerZ;
646
647 glGenTextures(1,&opaqueLayerRgba);
648 // opaque z format
649 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerZ);
650 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
651 GL_NEAREST);
652 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
653 GL_NEAREST);
654 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,
655 vtkgl::CLAMP_TO_EDGE);
656 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,
657 vtkgl::CLAMP_TO_EDGE);
658 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
659 vtkgl::TEXTURE_COMPARE_MODE,
660 vtkgl::COMPARE_R_TO_TEXTURE);
661 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
662 vtkgl::TEXTURE_COMPARE_FUNC,
663 GL_LESS);
664
665 // Allocate memory
666 glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB,0,this->DepthFormat,
667 this->ViewportWidth,this->ViewportHeight, 0,
668 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
669
670 // Grab the z-buffer
671 glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
672 this->ViewportY,this->ViewportWidth,
673 this->ViewportHeight);
674
675 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerRgba);
676 // opaque rgba format
677 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
678 GL_NEAREST);
679 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
680 GL_NEAREST);
681
682 // Allocate memory
683 glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
684 this->ViewportWidth,this->ViewportHeight, 0, GL_RGBA,
685 GL_UNSIGNED_BYTE, 0);
686
687 // Have to be set before a call to UpdateTranslucentPolygonalGeometry()
688 // because UpdateTranslucentPolygonalGeometry() will eventually call
689 // vtkOpenGLActor::Render() that uses this flag.
690 this->LastRenderingUsedDepthPeeling=1;
691
692 // Grab the rgba-buffer
693 glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
694 this->ViewportY,this->ViewportWidth,
695 this->ViewportHeight);
696
697 GLuint queryId;
698 vtkgl::GenQueries(1,&queryId);
699 int stop=0;
700 int infiniteLoop=this->MaximumNumberOfPeels==0;
701
702 unsigned int threshold=static_cast<unsigned int>(this->ViewportWidth*this->ViewportHeight*OcclusionRatio);
703 this->LayerList=new vtkOpenGLRendererLayerList;
704
705 // save the default blend function.
706 glPushAttrib(GL_COLOR_BUFFER_BIT);
707
708 int multiSampleStatus=glIsEnabled(vtkgl::MULTISAMPLE);
709
710 if(multiSampleStatus)
711 {
712 glDisable(vtkgl::MULTISAMPLE);
713 }
714 glDisable(GL_BLEND);
715 GLuint nbPixels=0;
716 GLuint previousNbPixels=0;
717 int l=0;
718 while(!stop)
719 {
720 vtkgl::BeginQuery(vtkgl::SAMPLES_PASSED,queryId);
721 stop=!this->RenderPeel(l);
722 vtkgl::EndQuery(vtkgl::SAMPLES_PASSED);
723 // blocking call
724 previousNbPixels=nbPixels;
725 if(!stop || l>0) // stop && l==0 <=> no translucent geometry
726 {
727 vtkgl::GetQueryObjectuiv(queryId,vtkgl::QUERY_RESULT,&nbPixels);
728 if(!stop)
729 {
730 stop=(nbPixels<=threshold) || (nbPixels==previousNbPixels);
731 ++l;
732 if(!stop && !infiniteLoop)
733 {
734 stop=l>=this->MaximumNumberOfPeels;
735 }
736 }
737 }
738 }
739 if(multiSampleStatus)
740 {
741 glEnable(vtkgl::MULTISAMPLE);
742 }
743 // The two following lines are taken from vtkOpenGLProperty to
744 // reset texturing state after rendering the props.
745 glDisable(GL_TEXTURE_2D);
746 glDisable (GL_ALPHA_TEST);
747 glDepthFunc(GL_LEQUAL);
748 vtkgl::DeleteQueries(1,&queryId);
749 if(this->TransparentLayerZ!=0)
750 {
751 GLuint transparentLayerZ=static_cast<GLuint>(this->TransparentLayerZ);
752 glDeleteTextures(1,&transparentLayerZ);
753 this->TransparentLayerZ=0;
754 }
755
756 // Finally, draw sorted opacity
757 glMatrixMode(GL_PROJECTION);
758 glPushMatrix();
759 glLoadIdentity();
760 glOrtho(0, this->ViewportWidth, 0, this->ViewportHeight, -1, 1);
761 glMatrixMode(GL_MODELVIEW);
762 glPushMatrix();
763 glLoadIdentity();
764 glClearColor( static_cast<GLclampf>(0),static_cast<GLclampf>(0),
765 static_cast<GLclampf>(0),static_cast<GLclampf>(0));
766
767 glClear(GL_COLOR_BUFFER_BIT);
768 glDisable(GL_DEPTH_TEST);
769
770 vtkgl::ActiveTexture(vtkgl::TEXTURE0 );
771 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
772 glEnable(vtkgl::TEXTURE_RECTANGLE_ARB);
773
774 // actor in wireframe may have change that
775 glPolygonMode(GL_FRONT, GL_FILL);
776
777 glDisable(GL_BLEND);
778 // First the opaque layer
779 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,opaqueLayerRgba);
780 glBegin(GL_QUADS);
781 glTexCoord2f(0, 0);
782 glVertex2f(0, 0);
783 glTexCoord2f(this->ViewportWidth, 0);
784 glVertex2f(this->ViewportWidth, 0);
785 glTexCoord2f(this->ViewportWidth, this->ViewportHeight);
786 glVertex2f(this->ViewportWidth, this->ViewportHeight);
787 glTexCoord2f(0, this->ViewportHeight);
788 glVertex2f(0, this->ViewportHeight);
789 glEnd();
790
791 vtkgl::BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
792 GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
793 glEnable(GL_BLEND);
794 // the transparent layers
795 std::list<GLuint>::reverse_iterator it=this->LayerList->List.rbegin();
796 std::list<GLuint>::reverse_iterator itEnd=this->LayerList->List.rend();
797 while(it!=itEnd)
798 {
799 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,(*it));
800
801 glBegin(GL_QUADS);
802 glTexCoord2f(0, 0);
803 glVertex2f(0, 0);
804 glTexCoord2f(this->ViewportWidth, 0);
805 glVertex2f(this->ViewportWidth, 0);
806 glTexCoord2f(this->ViewportWidth, this->ViewportHeight);
807 glVertex2f(this->ViewportWidth, this->ViewportHeight);
808 glTexCoord2f(0, this->ViewportHeight);
809 glVertex2f(0, this->ViewportHeight);
810 glEnd();
811 ++it;
812 }
813 // Restore the default blend function for the next stage (overlay)
814 glPopAttrib();
815
816 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
817 glDisable(vtkgl::TEXTURE_RECTANGLE_ARB);
818 glEnable(GL_DEPTH_TEST);
819 glMatrixMode(GL_PROJECTION);
820 glPopMatrix();
821 glMatrixMode(GL_MODELVIEW);
822 glPopMatrix();
823 // Destroy the shader
824 if(this->ProgramShader!=0)
825 {
826 vtkgl::DeleteProgram(this->ProgramShader);
827 this->ProgramShader=0;
828 }
829
830 // Destroy the layers
831 size_t c=this->LayerList->List.size();
832 GLuint *ids=new GLuint[c];
833 std::list<GLuint>::const_iterator it2=this->LayerList->List.begin();
834 size_t layer=0;
835 while(layer<c)
836 {
837 ids[layer]=(*it2);
838 ++layer;
839 ++it2;
840 }
841 glDeleteTextures(static_cast<GLsizei>(c),ids);
842 delete[] ids;
843 delete this->LayerList;
844 this->LayerList=0;
845
846 glDeleteTextures(1,&opaqueLayerRgba);
847 glDeleteTextures(1,&opaqueLayerZ);
848 }
849
850 vtkOpenGLCheckErrorMacro("failed after DeviceRenderTranslucentPolygonalGeometry");
851 }
852
853 // ----------------------------------------------------------------------------
854 // Description:
855 // Check the compilation status of some fragment shader source.
CheckCompilation(unsigned int fragmentShader)856 void vtkOpenGLRenderer::CheckCompilation(
857 unsigned int fragmentShader)
858 {
859 vtkOpenGLClearErrorMacro();
860 GLuint fs=static_cast<GLuint>(fragmentShader);
861 GLint params;
862 vtkgl::GetShaderiv(fs,vtkgl::COMPILE_STATUS,¶ms);
863 if(params==GL_TRUE)
864 {
865 vtkDebugMacro(<<"shader source compiled successfully");
866 }
867 else
868 {
869 vtkErrorMacro(<<"shader source compile error");
870 // include null terminator
871 vtkgl::GetShaderiv(fs,vtkgl::INFO_LOG_LENGTH,¶ms);
872 if(params>0)
873 {
874 char *buffer=new char[params];
875 vtkgl::GetShaderInfoLog(fs,params,0,buffer);
876 vtkErrorMacro(<<"log: "<<buffer);
877 delete[] buffer;
878 }
879 else
880 {
881 vtkErrorMacro(<<"no log");
882 }
883 }
884 vtkOpenGLCheckErrorMacro("failed after CheckCompilation");
885 }
886
887 // ----------------------------------------------------------------------------
888 // Description:
889 // Render a peel layer. If there is no more GPU RAM to save the texture,
890 // return false otherwise returns true. Also if layer==0 and no prop have
891 // been rendered (there is no translucent geometry), it returns false.
892 // \pre positive_layer: layer>=0
RenderPeel(int layer)893 int vtkOpenGLRenderer::RenderPeel(int layer)
894 {
895 assert("pre: positive_layer" && layer>=0);
896
897 vtkOpenGLClearErrorMacro();
898
899 GLbitfield mask=GL_COLOR_BUFFER_BIT;
900 if(layer>0)
901 {
902 mask=mask|GL_DEPTH_BUFFER_BIT;
903 }
904
905 glClearColor(0.0, 0.0, 0.0, 0.0);
906 glClear(mask);
907
908 vtkgl::ActiveTexture(vtkgl::TEXTURE2);
909 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->OpaqueLayerZ);
910 vtkgl::ActiveTexture(vtkgl::TEXTURE1 );
911
912 if(this->ProgramShader==0)
913 {
914 this->ProgramShader=vtkgl::CreateProgram();
915 GLuint shader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
916 vtkgl::ShaderSource(shader,1,const_cast<const char **>(&vtkOpenGLRenderer_PeelingFS),0);
917 vtkgl::CompileShader(shader);
918 this->CheckCompilation(shader);
919 vtkgl::AttachShader(this->ProgramShader,shader);
920 vtkgl::LinkProgram(this->ProgramShader);
921
922 GLint params;
923 vtkgl::GetProgramiv(static_cast<GLuint>(this->ProgramShader),vtkgl::LINK_STATUS,¶ms);
924 if(params==GL_TRUE)
925 {
926 vtkDebugMacro(<<"program linked successfully");
927 }
928 else
929 {
930 vtkErrorMacro(<<"program link error");
931 // include null terminator
932 vtkgl::GetProgramiv(static_cast<GLuint>(this->ProgramShader),vtkgl::INFO_LOG_LENGTH,¶ms);
933 if(params>0)
934 {
935 #if 1
936 char *buffer=new char[params];
937 vtkgl::GetProgramInfoLog(static_cast<GLuint>(this->ProgramShader),params,0,buffer);
938 vtkErrorMacro(<<"log: "<<buffer);
939 delete[] buffer;
940 #endif
941 }
942 else
943 {
944 vtkErrorMacro(<<"no log: ");
945 }
946 }
947 vtkgl::DeleteShader(shader); // reference counting
948 }
949
950 if(layer>0)
951 {
952 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
953 vtkgl::UseProgram(this->ProgramShader);
954 GLint uShadowTex=vtkgl::GetUniformLocation(this->ProgramShader,"shadowTex");
955 if(uShadowTex!=-1)
956 {
957 vtkgl::Uniform1i(uShadowTex,1);
958 }
959 else
960 {
961 vtkErrorMacro(<<"error: shadowTex is not a uniform.");
962 }
963 GLint uOpaqueShadowTex=vtkgl::GetUniformLocation(this->ProgramShader,"opaqueShadowTex");
964 if(uOpaqueShadowTex!=-1)
965 {
966 vtkgl::Uniform1i(uOpaqueShadowTex,2);
967 }
968 else
969 {
970 vtkErrorMacro(<<"error: opaqueShadowTex is not a uniform.");
971 }
972
973 GLint uOffsetX=vtkgl::GetUniformLocation(this->ProgramShader,"offsetX");
974 if(uOffsetX!=-1)
975 {
976 vtkgl::Uniform1f(uOffsetX,this->ViewportX);
977 }
978 else
979 {
980 vtkErrorMacro(<<"error: offsetX is not a uniform.");
981 }
982
983 GLint uOffsetY=vtkgl::GetUniformLocation(this->ProgramShader,"offsetY");
984 if(uOffsetY!=-1)
985 {
986 vtkgl::Uniform1f(uOffsetY,this->ViewportY);
987 }
988 else
989 {
990 vtkErrorMacro(<<"error: offsetY is not a uniform.");
991 }
992 }
993 vtkgl::ActiveTexture(vtkgl::TEXTURE0 );
994 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
995 this->DepthPeelingHigherLayer=layer>0;
996 int numberOfRenderedProps=this->UpdateTranslucentPolygonalGeometry();
997 if(layer>0)
998 {
999 this->DepthPeelingHigherLayer=0;
1000 vtkgl::UseProgram(0);
1001 }
1002
1003 vtkgl::ActiveTexture(vtkgl::TEXTURE1 );
1004 if(layer==0)
1005 {
1006 if(numberOfRenderedProps>0)
1007 {
1008 GLuint transparentLayerZ;
1009 glGenTextures(1,&transparentLayerZ);
1010 this->TransparentLayerZ=static_cast<unsigned int>(transparentLayerZ);
1011 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
1012
1013 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
1014 GL_NEAREST);
1015 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
1016 GL_NEAREST);
1017 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,
1018 vtkgl::CLAMP_TO_EDGE);
1019 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,
1020 vtkgl::CLAMP_TO_EDGE);
1021 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
1022 vtkgl::TEXTURE_COMPARE_MODE,
1023 vtkgl::COMPARE_R_TO_TEXTURE);
1024 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,
1025 vtkgl::TEXTURE_COMPARE_FUNC,
1026 GL_GREATER);
1027
1028 // Allocate memory, note: verified GPU support for this
1029 // texture format above.
1030 glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB,0,this->DepthFormat,
1031 this->ViewportWidth,this->ViewportHeight, 0,
1032 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
1033 }
1034 }
1035 else
1036 {
1037 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,this->TransparentLayerZ);
1038 }
1039 if((layer==0 && numberOfRenderedProps>0) || layer>0)
1040 {
1041 // Grab the z-buffer
1042 glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
1043 this->ViewportY,this->ViewportWidth,
1044 this->ViewportHeight);
1045
1046 // Grab the rgba buffer
1047 GLuint rgba;
1048 glGenTextures(1,&rgba);
1049 glBindTexture(vtkgl::TEXTURE_RECTANGLE_ARB,rgba);
1050 // rgba format
1051 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,
1052 GL_NEAREST);
1053 glTexParameteri(vtkgl::TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,
1054 GL_NEAREST);
1055
1056 // Allocate memory, note: verified GPU support for this
1057 // texture format above.
1058 glTexImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
1059 this->ViewportWidth,this->ViewportHeight, 0, GL_RGBA,
1060 GL_UNSIGNED_BYTE, 0);
1061
1062 // Grab the rgba-buffer
1063 glCopyTexSubImage2D(vtkgl::TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->ViewportX,
1064 this->ViewportY,this->ViewportWidth,
1065 this->ViewportHeight);
1066 this->LayerList->List.push_back(rgba);
1067
1068 vtkOpenGLCheckErrorMacro("failed after RenderPeel");
1069 return 1;
1070 }
1071 else
1072 {
1073 vtkOpenGLCheckErrorMacro("failed after RenderPeel");
1074 return 0;
1075 }
1076 }
1077
1078 // ----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1079 void vtkOpenGLRenderer::PrintSelf(ostream& os, vtkIndent indent)
1080 {
1081 this->Superclass::PrintSelf(os,indent);
1082
1083 os << indent << "Number Of Lights Bound: " <<
1084 this->NumberOfLightsBound << "\n";
1085 os << indent << "PickBuffer " << this->PickInfo->PickBuffer << "\n";
1086 os << indent << "PickedId" << this->PickInfo->PickedId<< "\n";
1087 os << indent << "NumPicked" << this->PickInfo->NumPicked<< "\n";
1088 os << indent << "PickedZ " << this->PickedZ << "\n";
1089 os << indent << "Pass:";
1090 if(this->Pass!=0)
1091 {
1092 os << "exists" << endl;
1093 }
1094 else
1095 {
1096 os << "null" << endl;
1097 }
1098 }
1099
1100
Clear(void)1101 void vtkOpenGLRenderer::Clear(void)
1102 {
1103 vtkOpenGLClearErrorMacro();
1104
1105 GLbitfield clear_mask = 0;
1106
1107 if (! this->Transparent())
1108 {
1109 glClearColor( static_cast<GLclampf>(this->Background[0]),
1110 static_cast<GLclampf>(this->Background[1]),
1111 static_cast<GLclampf>(this->Background[2]),
1112 static_cast<GLclampf>(0.0));
1113 clear_mask |= GL_COLOR_BUFFER_BIT;
1114 }
1115
1116 if (!this->GetPreserveDepthBuffer())
1117 {
1118 glClearDepth(static_cast<GLclampf>(1.0));
1119 clear_mask |= GL_DEPTH_BUFFER_BIT;
1120 }
1121
1122 vtkDebugMacro(<< "glClear\n");
1123 glClear(clear_mask);
1124
1125 // If gradient background is turned on, draw it now.
1126 if (!this->Transparent() &&
1127 (this->GradientBackground || this->TexturedBackground))
1128 {
1129 double tile_viewport[4];
1130 this->GetRenderWindow()->GetTileViewport(tile_viewport);
1131 glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT);
1132 glDisable(GL_ALPHA_TEST);
1133 glDisable(GL_DEPTH_TEST);
1134 glDisable(GL_LIGHTING);
1135 glDisable(GL_TEXTURE_1D);
1136 glDisable(GL_TEXTURE_2D);
1137 glDisable(GL_BLEND);
1138 glShadeModel(GL_SMOOTH); // color interpolation
1139
1140 glMatrixMode(GL_MODELVIEW);
1141 glPushMatrix();
1142 {
1143 glLoadIdentity();
1144 glMatrixMode(GL_PROJECTION);
1145 glPushMatrix();
1146 {
1147 glLoadIdentity();
1148 glOrtho(
1149 tile_viewport[0],
1150 tile_viewport[2],
1151 tile_viewport[1],
1152 tile_viewport[3],
1153 -1.0, 1.0);
1154
1155 //top vertices
1156 if(this->TexturedBackground && this->BackgroundTexture)
1157 {
1158 glEnable(GL_TEXTURE_2D);
1159
1160 this->BackgroundTexture->Render(this);
1161
1162 // NOTE: By default the mode is GL_MODULATE. Since the user
1163 // cannot set the mode, the default is set to replace.
1164 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1165 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1166 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1167
1168 // NOTE: vtkTexture Render enables the alpha test
1169 // so that no buffer is affected if alpha of incoming fragment is
1170 // below the threshold. Here we have to enable it so that it won't
1171 // rejects the fragments of the quad as the alpha is set to 0 on it.
1172 glDisable(GL_ALPHA_TEST);
1173 }
1174
1175 glBegin(GL_QUADS);
1176 glColor4d(this->Background[0],this->Background[1],this->Background[2],
1177 0.0);
1178 glTexCoord2f(0.0, 0.0);
1179 glVertex2f(0.0, 0.0);
1180
1181 glTexCoord2f(1.0, 0.0);
1182 glVertex2f(1.0, 0);
1183
1184 //bottom vertices
1185 glColor4d(this->Background2[0],this->Background2[1],
1186 this->Background2[2],0.0);
1187 glTexCoord2f(1.0, 1.0);
1188 glVertex2f(1.0, 1.0);
1189
1190 glTexCoord2f(0.0, 1.0);
1191 glVertex2f(0.0, 1.0);
1192
1193 glEnd();
1194 }
1195 glMatrixMode(GL_PROJECTION);
1196 glPopMatrix();
1197 }
1198 glMatrixMode(GL_MODELVIEW);
1199 glPopMatrix();
1200 glPopAttrib();
1201 }
1202 vtkOpenGLCheckErrorMacro("failed after Clear");
1203 }
1204
StartPick(unsigned int pickFromSize)1205 void vtkOpenGLRenderer::StartPick(unsigned int pickFromSize)
1206 {
1207 vtkOpenGLClearErrorMacro();
1208
1209 int bufferSize = pickFromSize * 4;
1210
1211 // Do not remove this MakeCurrent! Due to Start / End methods on
1212 // some objects which get executed during a pipeline update,
1213 // other windows might get rendered since the last time
1214 // a MakeCurrent was called.
1215 this->RenderWindow->MakeCurrent();
1216 this->RenderWindow->IsPickingOn();
1217 if (this->PickInfo->PickBuffer)
1218 {
1219 delete [] this->PickInfo->PickBuffer;
1220 this->PickInfo->PickBuffer = 0;
1221 }
1222 this->PickInfo->PickBuffer = new GLuint[bufferSize];
1223 glSelectBuffer(bufferSize, this->PickInfo->PickBuffer);
1224 // change to selection mode
1225 (void)glRenderMode(GL_SELECT);
1226 // initialize the pick names and add a 0 name, for no pick
1227 glInitNames();
1228 glPushName(0);
1229
1230 vtkOpenGLCheckErrorMacro("failed after StartPick");
1231 }
1232
ReleaseGraphicsResources(vtkWindow * w)1233 void vtkOpenGLRenderer::ReleaseGraphicsResources(vtkWindow *w)
1234 {
1235 if (w && this->Pass)
1236 {
1237 this->Pass->ReleaseGraphicsResources(w);
1238 }
1239 }
1240
UpdatePickId()1241 void vtkOpenGLRenderer::UpdatePickId()
1242 {
1243 glLoadName(this->CurrentPickId++);
1244 vtkOpenGLCheckErrorMacro("failed after UpdatePick");
1245 }
1246
1247
DevicePickRender()1248 void vtkOpenGLRenderer::DevicePickRender()
1249 {
1250 // Do not remove this MakeCurrent! Due to Start / End methods on
1251 // some objects which get executed during a pipeline update,
1252 // other windows might get rendered since the last time
1253 // a MakeCurrent was called.
1254 this->RenderWindow->MakeCurrent();
1255 vtkOpenGLClearErrorMacro();
1256
1257 // standard render method
1258 this->ClearLights();
1259
1260 this->UpdateCamera();
1261 this->UpdateLightGeometry();
1262 this->UpdateLights();
1263
1264 // set matrix mode for actors
1265 glMatrixMode(GL_MODELVIEW);
1266
1267 this->PickGeometry();
1268
1269 // clean up the model view matrix set up by the camera
1270 glMatrixMode(GL_MODELVIEW);
1271 glPopMatrix();
1272 vtkOpenGLCheckErrorMacro("failed after DevicePickRender");
1273 }
1274
1275
DonePick()1276 void vtkOpenGLRenderer::DonePick()
1277 {
1278 glFlush();
1279 GLuint hits = glRenderMode(GL_RENDER);
1280 this->PickInfo->NumPicked = hits;
1281
1282 unsigned int depth = static_cast<unsigned int>(-1);
1283 GLuint* ptr = this->PickInfo->PickBuffer;
1284 this->PickInfo->PickedId = 0;
1285 for(unsigned int k =0; k < hits; k++)
1286 {
1287 int num_names = *ptr;
1288 int save = 0;
1289 ptr++; // move to first depth value
1290 if(*ptr <= depth)
1291 {
1292 depth = *ptr;
1293 save = 1;
1294 }
1295 ptr++; // move to next depth value
1296 if(*ptr <= depth)
1297 {
1298 depth = *ptr;
1299 save = 1;
1300 }
1301 // move to first name picked
1302 ptr++;
1303 if(save)
1304 {
1305 this->PickInfo->PickedId = *ptr;
1306 }
1307 // skip additional names
1308 ptr += num_names;
1309 }
1310 // If there was a pick, then get the Z value
1311 if(this->PickInfo->PickedId)
1312 {
1313 // convert from pick depth described as:
1314 // Returned depth values are mapped such that the largest unsigned
1315 // integer value corresponds to window coordinate depth 1.0,
1316 // and zero corresponds to window coordinate depth 0.0.
1317
1318 this->PickedZ = depth/static_cast<double>(VTK_UNSIGNED_INT_MAX);
1319
1320 // Clamp to range [0,1]
1321 this->PickedZ = (this->PickedZ < 0.0) ? 0.0 : this->PickedZ;
1322 this->PickedZ = (this->PickedZ > 1.0) ? 1.0: this->PickedZ;
1323 }
1324
1325 //Don't delete the list, keep it around in case caller wants all
1326 //of the hits. Delete it elsewhere when needed.
1327 //delete [] this->PickInfo->PickBuffer;
1328 //this->PickInfo->PickBuffer = 0;
1329
1330 this->RenderWindow->IsPickingOff();
1331 }
1332
GetPickedZ()1333 double vtkOpenGLRenderer::GetPickedZ()
1334 {
1335 return this->PickedZ;
1336 }
1337
GetPickedId()1338 unsigned int vtkOpenGLRenderer::GetPickedId()
1339 {
1340 return static_cast<unsigned int>(this->PickInfo->PickedId);
1341 }
1342
~vtkOpenGLRenderer()1343 vtkOpenGLRenderer::~vtkOpenGLRenderer()
1344 {
1345 if (this->PickInfo->PickBuffer)
1346 {
1347 delete [] this->PickInfo->PickBuffer;
1348 this->PickInfo->PickBuffer = 0;
1349 }
1350 delete this->PickInfo;
1351
1352 if(this->ShaderProgram!=0)
1353 {
1354 this->ShaderProgram->Delete();
1355 }
1356
1357 if(this->Pass!=0)
1358 {
1359 this->Pass->UnRegister(this);
1360 }
1361 }
1362
GetNumPickedIds()1363 unsigned int vtkOpenGLRenderer::GetNumPickedIds()
1364 {
1365 return static_cast<unsigned int>(this->PickInfo->NumPicked);
1366 }
1367
GetPickedIds(unsigned int atMost,unsigned int * callerBuffer)1368 int vtkOpenGLRenderer::GetPickedIds(unsigned int atMost,
1369 unsigned int *callerBuffer)
1370 {
1371 if (!this->PickInfo->PickBuffer)
1372 {
1373 return 0;
1374 }
1375
1376 unsigned int max = (atMost < this->PickInfo->NumPicked) ? atMost : this->PickInfo->NumPicked;
1377 GLuint* iptr = this->PickInfo->PickBuffer;
1378 unsigned int *optr = callerBuffer;
1379 unsigned int k;
1380 for(k =0; k < max; k++)
1381 {
1382 int num_names = *iptr;
1383 iptr++; // move to first depth value
1384 iptr++; // move to next depth value
1385 iptr++; // move to first name picked
1386 *optr = static_cast<unsigned int>(*iptr);
1387 optr++;
1388 // skip additional names
1389 iptr += num_names;
1390 }
1391 return k;
1392 }
1393