vtkOpenGLRenderer.cxx 20.4 KB
Newer Older
1
2
3
/*=========================================================================

Program:   Visualization Toolkit
4
Module:    vtkOpenGLRenderer.cxx
5
6
7
8
9
10
11
12
13
14

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.

=========================================================================*/
15
#include "vtkOpenGLRenderer.h"
16

Ken Martin's avatar
Ken Martin committed
17
#include "vtkOpenGLHelper.h"
18

19
#include "vtkCellArray.h"
20
#include "vtkDepthPeelingPass.h"
21
#include "vtkFloatArray.h"
Ken Martin's avatar
Ken Martin committed
22
#include "vtkHardwareSelector.h"
23
#include "vtkLight.h"
24
#include "vtkLightCollection.h"
25
#include "vtkNew.h"
26
#include "vtkObjectFactory.h"
27
#include "vtkOpenGLCamera.h"
28
#include "vtkOpenGLError.h"
29
#include "vtkOpenGLRenderWindow.h"
30
31
32
33
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper2D.h"
34
35
#include "vtkRenderPass.h"
#include "vtkRenderState.h"
Ken Martin's avatar
Ken Martin committed
36
37
#include "vtkShadowMapBakerPass.h"
#include "vtkShadowMapPass.h"
38
#include "vtkTexture.h"
39
#include "vtkTextureObject.h"
40
41
#include "vtkTexturedActor2D.h"
#include "vtkTimerLog.h"
42
#include "vtkTranslucentPass.h"
43
44
#include "vtkTrivialProducer.h"
#include "vtkUnsignedCharArray.h"
45

Sean McBride's avatar
Sean McBride committed
46
#include <cmath>
47
48
49
50
51
52
#include <cassert>
#include <list>

class vtkGLPickInfo
{
public:
Ken Martin's avatar
Ken Martin committed
53
54
  unsigned int PickedId;
  unsigned int NumPicked;
55
56
  bool PerformedHardwarePick;
  std::map<unsigned int,float> PickValues;
57
58
};

59
vtkStandardNewMacro(vtkOpenGLRenderer);
60

61
vtkCxxSetObjectMacro(vtkOpenGLRenderer, Pass, vtkRenderPass);
62

63
vtkOpenGLRenderer::vtkOpenGLRenderer()
64
65
66
67
68
69
{
  this->PickInfo = new vtkGLPickInfo;
  this->PickInfo->PickedId = 0;
  this->PickInfo->NumPicked = 0;
  this->PickedZ = 0;

70
  this->DepthPeelingPass = 0;
Ken Martin's avatar
Ken Martin committed
71
  this->ShadowMapPass = 0;
72
73
74
75
  this->DepthPeelingHigherLayer=0;

  this->BackgroundTexture = 0;
  this->Pass = 0;
76
77
78

  this->HaveApplePrimitiveIdBugValue = false;
  this->HaveApplePrimitiveIdBugChecked = false;
79
80
81
}

// Ask lights to load themselves into graphics pipeline.
82
int vtkOpenGLRenderer::UpdateLights ()
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
{
  vtkOpenGLClearErrorMacro();

  vtkLight *light;
  float status;
  int count = 0;

  vtkCollectionSimpleIterator sit;
  for(this->Lights->InitTraversal(sit);
      (light = this->Lights->GetNextLight(sit)); )
    {
    status = light->GetSwitch();
    if (status > 0.0)
      {
      count++;
      }
    }

  if( !count )
    {
    vtkDebugMacro(<<"No lights are on, creating one.");
    this->CreateLight();
    }

  for(this->Lights->InitTraversal(sit);
      (light = this->Lights->GetNextLight(sit)); )
    {
    status = light->GetSwitch();

    // if the light is on then define it and bind it.
    if (status > 0.0)
      {
      light->Render(this,0);
      }
    }

  vtkOpenGLCheckErrorMacro("failed after UpdateLights");

  return count;
}

// ----------------------------------------------------------------------------
// Description:
// Is rendering at translucent geometry stage using depth peeling and
// rendering a layer other than the first one? (Boolean value)
// If so, the uniform variables UseTexture and Texture can be set.
// (Used by vtkOpenGLProperty or vtkOpenGLTexture)
130
int vtkOpenGLRenderer::GetDepthPeelingHigherLayer()
131
132
133
134
135
136
{
  return this->DepthPeelingHigherLayer;
}

// ----------------------------------------------------------------------------
// Concrete open gl render method.
137
void vtkOpenGLRenderer::DeviceRender(void)
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
{
  vtkTimerLog::MarkStartEvent("OpenGL Dev Render");

  if(this->Pass!=0)
    {
    vtkRenderState s(this);
    s.SetPropArrayAndCount(this->PropArray, this->PropArrayCount);
    s.SetFrameBuffer(0);
    this->Pass->Render(&s);
    }
  else
    {
    // Do not remove this MakeCurrent! Due to Start / End methods on
    // some objects which get executed during a pipeline update,
    // other windows might get rendered since the last time
    // a MakeCurrent was called.
    this->RenderWindow->MakeCurrent();
    vtkOpenGLClearErrorMacro();

    this->UpdateCamera();
    this->UpdateLightGeometry();
    this->UpdateLights();
    this->UpdateGeometry();

    vtkOpenGLCheckErrorMacro("failed after DeviceRender");
    }

  vtkTimerLog::MarkEndEvent("OpenGL Dev Render");
}

Ken Martin's avatar
Ken Martin committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
// Ask actors to render themselves. As a side effect will cause
// visualization network to update.
int vtkOpenGLRenderer::UpdateGeometry()
{
  int        i;

  this->NumberOfPropsRendered = 0;

  if ( this->PropArrayCount == 0 )
    {
    return 0;
    }

  if (this->Selector)
    {
    // When selector is present, we are performing a selection,
    // so do the selection rendering pass instead of the normal passes.
    // Delegate the rendering of the props to the selector itself.
    this->NumberOfPropsRendered = this->Selector->Render(this,
      this->PropArray, this->PropArrayCount);
    this->RenderTime.Modified();
    vtkDebugMacro("Rendered " << this->NumberOfPropsRendered << " actors" );
    return this->NumberOfPropsRendered;
    }

  // if we are suing shadows then let the renderpasses handle it
  // for opaque and translucent
  if (this->UseShadows)
    {
    if (!this->ShadowMapPass)
      {
      this->ShadowMapPass = vtkShadowMapPass::New();
      }
    vtkRenderState s(this);
    s.SetPropArrayAndCount(this->PropArray, this->PropArrayCount);
    //s.SetFrameBuffer(0);
    this->ShadowMapPass->GetShadowMapBakerPass()->Render(&s);
    this->ShadowMapPass->Render(&s);
    }
  else
    {
    // loop through props and give them a chance to
    // render themselves as opaque geometry
    for ( i = 0; i < this->PropArrayCount; i++ )
      {
      this->NumberOfPropsRendered +=
        this->PropArray[i]->RenderOpaqueGeometry(this);
      }

    // do the render library specific stuff about translucent polygonal geometry.
    // As it can be expensive, do a quick check if we can skip this step
    int hasTranslucentPolygonalGeometry=0;
    for ( i = 0; !hasTranslucentPolygonalGeometry && i < this->PropArrayCount;
          i++ )
      {
      hasTranslucentPolygonalGeometry=
        this->PropArray[i]->HasTranslucentPolygonalGeometry();
      }
    if(hasTranslucentPolygonalGeometry)
      {
      this->DeviceRenderTranslucentPolygonalGeometry();
      }
    }

  // loop through props and give them a chance to
  // render themselves as volumetric geometry.
  for ( i = 0; i < this->PropArrayCount; i++ )
    {
    this->NumberOfPropsRendered +=
      this->PropArray[i]->RenderVolumetricGeometry(this);
    }

  // loop through props and give them a chance to
  // render themselves as an overlay (or underlay)
  for ( i = 0; i < this->PropArrayCount; i++ )
    {
    this->NumberOfPropsRendered +=
      this->PropArray[i]->RenderOverlay(this);
    }

  this->RenderTime.Modified();

  vtkDebugMacro( << "Rendered " <<
                    this->NumberOfPropsRendered << " actors" );

  return  this->NumberOfPropsRendered;
}

256
257
258
259
260
261
// ----------------------------------------------------------------------------
// Description:
// Render translucent polygonal geometry. Default implementation just call
// UpdateTranslucentPolygonalGeometry().
// Subclasses of vtkRenderer that can deal with depth peeling must
// override this method.
262
void vtkOpenGLRenderer::DeviceRenderTranslucentPolygonalGeometry()
263
264
265
{
  vtkOpenGLClearErrorMacro();

266
267
  vtkOpenGLRenderWindow *context
    = vtkOpenGLRenderWindow::SafeDownCast(this->RenderWindow);
Ken Martin's avatar
Ken Martin committed
268

269
270
271
272
  if(this->UseDepthPeeling && !context)
    {
    vtkErrorMacro("OpenGL render window is required.")
    return;
273
274
    }

275
  if(!this->UseDepthPeeling)
276
277
278
279
    {
    // just alpha blending
    this->UpdateTranslucentPolygonalGeometry();
    }
Ken Martin's avatar
Ken Martin committed
280
  else   // depth peeling.
281
    {
282
    if (!this->DepthPeelingPass)
Ken Martin's avatar
Ken Martin committed
283
      {
284
285
286
287
      this->DepthPeelingPass = vtkDepthPeelingPass::New();
      vtkTranslucentPass *tp = vtkTranslucentPass::New();
      this->DepthPeelingPass->SetTranslucentPass(tp);
      tp->Delete();
Ken Martin's avatar
Ken Martin committed
288
      }
289
290
291
292
293
    this->DepthPeelingPass->SetMaximumNumberOfPeels(this->MaximumNumberOfPeels);
    this->DepthPeelingPass->SetOcclusionRatio(this->OcclusionRatio);
    vtkRenderState s(this);
    s.SetPropArrayAndCount(this->PropArray, this->PropArrayCount);
    s.SetFrameBuffer(0);
294
    this->LastRenderingUsedDepthPeeling=1;
295
    this->DepthPeelingPass->Render(&s);
296
297
298
299
300
    }

  vtkOpenGLCheckErrorMacro("failed after DeviceRenderTranslucentPolygonalGeometry");
}

Ken Martin's avatar
Ken Martin committed
301

302
// ----------------------------------------------------------------------------
303
void vtkOpenGLRenderer::PrintSelf(ostream& os, vtkIndent indent)
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "PickedId" << this->PickInfo->PickedId<< "\n";
  os << indent << "NumPicked" << this->PickInfo->NumPicked<< "\n";
  os << indent << "PickedZ " << this->PickedZ << "\n";
  os << indent << "Pass:";
  if(this->Pass!=0)
    {
      os << "exists" << endl;
    }
  else
    {
      os << "null" << endl;
    }
}


322
void vtkOpenGLRenderer::Clear(void)
323
324
325
326
327
328
329
{
  vtkOpenGLClearErrorMacro();

  GLbitfield  clear_mask = 0;

  if (! this->Transparent())
    {
330
331
332
333
334
335
336
337
338
339
340
    if (this->IsPicking)
      {
      glClearColor(0.0,0.0,0.0,0.0);
      }
    else
      {
      glClearColor( static_cast<GLclampf>(this->Background[0]),
                    static_cast<GLclampf>(this->Background[1]),
                    static_cast<GLclampf>(this->Background[2]),
                    static_cast<GLclampf>(0.0));
      }
341
342
343
    clear_mask |= GL_COLOR_BUFFER_BIT;
    }

Ken Martin's avatar
Ken Martin committed
344
345
  if (!this->GetPreserveDepthBuffer())
    {
Ken Martin's avatar
Ken Martin committed
346
347
348
#if GL_ES_VERSION_2_0 == 1
    glClearDepthf(static_cast<GLclampf>(1.0));
#else
349
    glClearDepth(static_cast<GLclampf>(1.0));
Ken Martin's avatar
Ken Martin committed
350
#endif
Ken Martin's avatar
Ken Martin committed
351
    clear_mask |= GL_DEPTH_BUFFER_BIT;
352
    glDepthMask(GL_TRUE);
Ken Martin's avatar
Ken Martin committed
353
354
    }

355
  vtkDebugMacro(<< "glClear\n");
Ken Martin's avatar
Ken Martin committed
356
  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
357
358
359
  glClear(clear_mask);

  // If gradient background is turned on, draw it now.
360
  if (!this->IsPicking && !this->Transparent() &&
361
362
      (this->GradientBackground || this->TexturedBackground))
    {
Ken Martin's avatar
Ken Martin committed
363
364
365
366
    int size[2];
    size[0] = this->GetSize()[0];
    size[1] = this->GetSize()[1];

367
368
    double tile_viewport[4];
    this->GetRenderWindow()->GetTileViewport(tile_viewport);
Ken Martin's avatar
Ken Martin committed
369

370
    vtkNew<vtkTexturedActor2D> actor;
Ken Martin's avatar
Ken Martin committed
371
372
373
374
375
376
377
378
    vtkNew<vtkPolyDataMapper2D> mapper;
    vtkNew<vtkPolyData> polydata;
    vtkNew<vtkPoints> points;
    points->SetNumberOfPoints(4);
    points->SetPoint(0, 0, 0, 0);
    points->SetPoint(1, size[0], 0, 0);
    points->SetPoint(2, size[0], size[1], 0);
    points->SetPoint(3, 0, size[1], 0);
379
    polydata->SetPoints(points.Get());
Ken Martin's avatar
Ken Martin committed
380
381
382
383
384
385

    vtkNew<vtkCellArray> tris;
    tris->InsertNextCell(3);
    tris->InsertCellPoint(0);
    tris->InsertCellPoint(1);
    tris->InsertCellPoint(2);
Ken Martin's avatar
Ken Martin committed
386
    tris->InsertNextCell(3);
Ken Martin's avatar
Ken Martin committed
387
388
389
390
391
392
393
394
395
396
397
398
399
    tris->InsertCellPoint(0);
    tris->InsertCellPoint(2);
    tris->InsertCellPoint(3);
    polydata->SetPolys(tris.Get());

    vtkNew<vtkTrivialProducer> prod;
    prod->SetOutput(polydata.Get());

    // Set some properties.
    mapper->SetInputConnection(prod->GetOutputPort());
    actor->SetMapper(mapper.Get());

    if(this->TexturedBackground && this->BackgroundTexture)
400
      {
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
      this->BackgroundTexture->InterpolateOn();
      actor->SetTexture(this->BackgroundTexture);

      vtkNew<vtkFloatArray> tcoords;
      float tmp[2];
      tmp[0] = 0;
      tmp[1] = 0;
      tcoords->SetNumberOfComponents(2);
      tcoords->SetNumberOfTuples(4);
      tcoords->SetTuple(0,tmp);
      tmp[0] = 1.0;
      tcoords->SetTuple(1,tmp);
      tmp[1] = 1.0;
      tcoords->SetTuple(2,tmp);
      tmp[0] = 0.0;
      tcoords->SetTuple(3,tmp);
      polydata->GetPointData()->SetTCoords(tcoords.Get());
      }
    else // gradient
      {
      vtkNew<vtkUnsignedCharArray> colors;
      float tmp[4];
      tmp[0] = this->Background[0]*255;
      tmp[1] = this->Background[1]*255;
      tmp[2] = this->Background[2]*255;
      tmp[3] = 255;
      colors->SetNumberOfComponents(4);
      colors->SetNumberOfTuples(4);
      colors->SetTuple(0,tmp);
      colors->SetTuple(1,tmp);
      tmp[0] = this->Background2[0]*255;
      tmp[1] = this->Background2[1]*255;
      tmp[2] = this->Background2[2]*255;
      colors->SetTuple(2,tmp);
      colors->SetTuple(3,tmp);
      polydata->GetPointData()->SetScalars(colors.Get());
      }
438

439
440
441
    glDisable(GL_DEPTH_TEST);
    actor->RenderOverlay(this);
    }
442

443
  glEnable(GL_DEPTH_TEST);
Ken Martin's avatar
Ken Martin committed
444

445
446
447
  vtkOpenGLCheckErrorMacro("failed after Clear");
}

448
void vtkOpenGLRenderer::StartPick(unsigned int vtkNotUsed(pickFromSize))
449
450
451
{
  vtkOpenGLClearErrorMacro();

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
  /*
  int size[2];
  size[0] = this->GetSize()[0];
  size[1] = this->GetSize()[1];

  // Create the FBO
  glGenFramebuffers(1, &this->PickInfo->PickingFBO);
  glBindFramebuffer(GL_FRAMEBUFFER, this->PickInfo->PickingFBO);

  // Create the texture object for the primitive information buffer
  glGenTextures(1, &this->PickInfo->PickingTexture);
  glBindTexture(GL_TEXTURE_2D, this->PickInfo->PickingTexture);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, size[0], size[1],
              0, GL_RGB_INTEGER, GL_UNSIGNED_INT, NULL);
  glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
              this->PickInfo->PickingTexture, 0);

  // Create the texture object for the depth buffer
  glGenTextures(1, &this->PickInfo->DepthTexture);
  glBindTexture(GL_TEXTURE_2D, this->PickInfo->DepthTexture);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size[0], size[1],
              0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
              this->PickInfo->DepthTexture, 0);

  // Disable reading to avoid problems with older GPUs
  glReadBuffer(GL_NONE);

  // Verify that the FBO is correct
  GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

  if (Status != GL_FRAMEBUFFER_COMPLETE)
    {
    printf("FB error, status: 0x%x\n", Status);
    return;
    }

  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->PickInfo->PickingFBO);
  */
491
492
493
494
495
496
497

  // Do not remove this MakeCurrent! Due to Start / End methods on
  // some objects which get executed during a pipeline update,
  // other windows might get rendered since the last time
  // a MakeCurrent was called.
  this->RenderWindow->MakeCurrent();
  this->RenderWindow->IsPickingOn();
498
  this->IsPicking = 1;
499
500
501
502
503
  this->PickInfo->PerformedHardwarePick = false;
  this->PickInfo->PickValues.clear();
  this->PickInfo->NumPicked = 0;
  this->PickInfo->PickedId = 0;

504
  this->Clear();
505
506
507
508

  vtkOpenGLCheckErrorMacro("failed after StartPick");
}

509
void vtkOpenGLRenderer::ReleaseGraphicsResources(vtkWindow *w)
510
511
512
513
514
{
  if (w && this->Pass)
    {
    this->Pass->ReleaseGraphicsResources(w);
    }
515
516
517
518
  if (w && this->DepthPeelingPass)
    {
    this->DepthPeelingPass->ReleaseGraphicsResources(w);
    }
Ken Martin's avatar
Ken Martin committed
519
520
521
522
  if (w && this->ShadowMapPass)
    {
    this->ShadowMapPass->ReleaseGraphicsResources(w);
    }
523
  this->Superclass::ReleaseGraphicsResources(w);
524
525
}

526
void vtkOpenGLRenderer::UpdatePickId()
527
{
528
  this->CurrentPickId++;
529
530
531
}


532
void vtkOpenGLRenderer::DevicePickRender()
533
534
535
536
537
538
539
540
541
542
543
544
545
546
{
  // Do not remove this MakeCurrent! Due to Start / End methods on
  // some objects which get executed during a pipeline update,
  // other windows might get rendered since the last time
  // a MakeCurrent was called.
  this->RenderWindow->MakeCurrent();
  vtkOpenGLClearErrorMacro();

  this->UpdateCamera();
  this->UpdateLightGeometry();
  this->UpdateLights();

  this->PickGeometry();

547
548
  this->PickInfo->PerformedHardwarePick = true;

549
550
551
552
  vtkOpenGLCheckErrorMacro("failed after DevicePickRender");
}


553
void vtkOpenGLRenderer::DonePick()
554
{
555
  if (this->PickInfo->PerformedHardwarePick)
556
    {
557
558
559
560
561
    unsigned char *pixBuffer = this->GetRenderWindow()->GetPixelData(
      this->PickX1, this->PickY1, this->PickX2, this->PickY2, 0);
  //    (this->GetRenderWindow()->GetSwapBuffers() == 1) ? 0 : 1);

    // for debugging save out the image
562
563
564
565
    // FILE * pFile;
    // pFile = fopen ("myfile.ppm", "wb");
    // fwrite (pixBuffer , sizeof(unsigned char), 3*((int)this->PickY2-(int)this->PickY1+1)*((int)this->PickX2-(int)this->PickX1+1), pFile);
    // fclose (pFile);
566
567
568
569
570
571
572
573
574
575

    float *depthBuffer = this->GetRenderWindow()->GetZbufferData(
      this->PickX1, this->PickY1, this->PickX2, this->PickY2);

    // read the color and z buffer values for the region
    // to see what hits we have
    this->PickInfo->PickValues.clear();
    unsigned char *pb = pixBuffer;
    float *dbPtr = depthBuffer;
    for (int y = this->PickY1; y <= this->PickY2; y++)
576
      {
577
      for (int x = this->PickX1; x <= this->PickX2; x++)
578
        {
579
580
581
582
583
584
585
586
587
588
589
        unsigned char rgb[3];
        rgb[0] = *pb++;
        rgb[1] = *pb++;
        rgb[2] = *pb++;
        int val = 0;
        val |= rgb[2];
        val = val << 8;
        val |= rgb[1];
        val = val << 8;
        val |= rgb[0];
        if (val > 0)
590
          {
591
592
593
594
          if (this->PickInfo->PickValues.find(val) == this->PickInfo->PickValues.end())
            {
            this->PickInfo->PickValues.insert(std::pair<unsigned int,float>(val,*dbPtr));
            }
595
          }
596
        dbPtr++;
597
        }
598
599
      }

Ken Martin's avatar
Ken Martin committed
600
    this->PickInfo->NumPicked = (unsigned int)this->PickInfo->PickValues.size();
601

602
603
604
605
606
    this->PickInfo->PickedId = 0;
    std::map<unsigned int,float>::const_iterator dvItr =
      this->PickInfo->PickValues.begin();
    this->PickedZ = 1.0;
    for ( ; dvItr != this->PickInfo->PickValues.end(); dvItr++)
607
      {
608
609
610
611
612
      if(dvItr->second < this->PickedZ)
        {
        this->PickedZ = dvItr->second;
        this->PickInfo->PickedId = dvItr->first - 1;
        }
613
      }
614
615
    }

616
617
  // Restore the default framebuffer
  //glBindFramebuffer(GL_FRAMEBUFFER, 0);
618
619

  this->RenderWindow->IsPickingOff();
620
  this->IsPicking = 0;
621
622
}

623
double vtkOpenGLRenderer::GetPickedZ()
624
625
626
627
{
  return this->PickedZ;
}

628
unsigned int vtkOpenGLRenderer::GetPickedId()
629
630
631
632
{
  return static_cast<unsigned int>(this->PickInfo->PickedId);
}

633
vtkOpenGLRenderer::~vtkOpenGLRenderer()
634
635
636
{
  delete this->PickInfo;

Ken Martin's avatar
Ken Martin committed
637
  if(this->Pass != NULL)
638
639
    {
    this->Pass->UnRegister(this);
Ken Martin's avatar
Ken Martin committed
640
641
642
    this->Pass = NULL;
    }

Ken Martin's avatar
Ken Martin committed
643
644
645
646
647
648
  if (this->ShadowMapPass)
    {
    this->ShadowMapPass->Delete();
    this->ShadowMapPass = 0;
    }

649
  if (this->DepthPeelingPass)
Ken Martin's avatar
Ken Martin committed
650
    {
651
652
    this->DepthPeelingPass->Delete();
    this->DepthPeelingPass = 0;
653
654
655
    }
}

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
bool vtkOpenGLRenderer::HaveApplePrimitiveIdBug()
{
  if (this->HaveApplePrimitiveIdBugChecked)
    {
    return this->HaveApplePrimitiveIdBugValue;
    }

#ifdef __APPLE__
  // working AMD APPLE systems
  // OpenGL vendor string:  ATI Technologies Inc.
  // OpenGL version string:   4.1 ATI-1.40.15
  // OpenGL renderer string:    AMD Radeon R9 M370X OpenGL Engine
  // OpenGL version string:   4.1 ATI-1.40.16
  // OpenGL renderer string:    AMD Radeon HD - FirePro D500 OpenGL Engine
  // OpenGL renderer string:    AMD Radeon HD 5770 OpenGL Engine

  // known bad APPLE AMD systems
  // OpenGL vendor string:  ATI Technologies Inc.
  // OpenGL version string:   3.3 ATI-10.0.40
  // OpenGL renderer string:    ATI Radeon HD 2600 PRO OpenGL Engine

  std::string vendor = (const char *)glGetString(GL_VENDOR);
  if (vendor.find("ATI") != std::string::npos ||
      vendor.find("AMD") != std::string::npos ||
      vendor.find("amd") != std::string::npos)
    {
    // assume we have the bug
    this->HaveApplePrimitiveIdBugValue = true;

    // but exclude systems we know do not have it
    std::string renderer = (const char *)glGetString(GL_RENDERER);
    std::string version = (const char *)glGetString(GL_VERSION);
    if (
        (version.find("4.1 ATI-1.40.15") != std::string::npos &&
          (renderer.find("AMD Radeon R9 M370X OpenGL Engine") != std::string::npos)) ||
        (version.find("4.1 ATI-1.40.16") != std::string::npos &&
          (renderer.find("ATI Radeon HD 5770 OpenGL Engine") != std::string::npos ||
           renderer.find("AMD Radeon HD - FirePro D500 OpenGL Engine") != std::string::npos))
        )
      {
      this->HaveApplePrimitiveIdBugValue = false;
      }
    }
#else
  this->HaveApplePrimitiveIdBugValue = false;
#endif

  this->HaveApplePrimitiveIdBugChecked = true;
  return this->HaveApplePrimitiveIdBugValue;
}

707
unsigned int vtkOpenGLRenderer::GetNumPickedIds()
708
709
710
711
{
  return static_cast<unsigned int>(this->PickInfo->NumPicked);
}

712
int vtkOpenGLRenderer::GetPickedIds(unsigned int atMost,
713
714
                                    unsigned int *callerBuffer)
{
715
  if (this->PickInfo->PickValues.empty())
716
717
718
719
720
    {
    return 0;
    }

  unsigned int max = (atMost < this->PickInfo->NumPicked) ? atMost : this->PickInfo->NumPicked;
721
722

  unsigned int k = 0;
723
  unsigned int *optr = callerBuffer;
724
725
726
727
  std::map<unsigned int,float>::const_iterator dvItr =
    this->PickInfo->PickValues.begin();
  this->PickedZ = 1.0;
  for ( ; dvItr != this->PickInfo->PickValues.end() && k < max; dvItr++)
728
    {
729
    *optr = static_cast<unsigned int>(dvItr->first);
730
731
732
733
    optr++;
    }
  return k;
}