vtkOpenGLImageMapper.cxx 19.1 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1 2 3
/*=========================================================================

  Program:   Visualization Toolkit
4
  Module:    vtkOpenGLImageMapper.cxx
Ken Martin's avatar
Ken Martin committed
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 "vtkOpenGLImageMapper.h"
Ken Martin's avatar
Ken Martin committed
16

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

Ken Martin's avatar
Ken Martin committed
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#include "vtkActor2D.h"
#include "vtkDataArray.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#include "vtkViewport.h"
#
#include "vtkWindow.h"

#include "vtkPolyDataMapper2D.h"
#include "vtkProperty2D.h"
#include "vtkPoints.h"
#include "vtkUnsignedCharArray.h"
#include "vtkFloatArray.h"
#include "vtkPolyData.h"
#include "vtkPointData.h"
#include "vtkCellArray.h"
#include "vtkTrivialProducer.h"
#include "vtkTexturedActor2D.h"
#include "vtkTexture.h"

#include "vtkNew.h"

#include "vtkOpenGLError.h"

43
vtkStandardNewMacro(vtkOpenGLImageMapper);
Ken Martin's avatar
Ken Martin committed
44

45
vtkOpenGLImageMapper::vtkOpenGLImageMapper()
Ken Martin's avatar
Ken Martin committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
{
  this->Actor = vtkTexturedActor2D::New();
  vtkNew<vtkPolyDataMapper2D> mapper;
  vtkNew<vtkPolyData> polydata;
  vtkNew<vtkPoints> points;
  points->SetNumberOfPoints(4);
  polydata->SetPoints(points.Get());

  vtkNew<vtkCellArray> tris;
  tris->InsertNextCell(3);
  tris->InsertCellPoint(0);
  tris->InsertCellPoint(1);
  tris->InsertCellPoint(2);
  tris->InsertNextCell(3);
  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());
  this->Actor->SetMapper(mapper.Get());

  vtkNew<vtkTexture> texture;
  texture->RepeatOff();
  this->Actor->SetTexture(texture.Get());

  vtkNew<vtkFloatArray> tcoords;
  tcoords->SetNumberOfComponents(2);
  tcoords->SetNumberOfTuples(4);
  polydata->GetPointData()->SetTCoords(tcoords.Get());
}

82
vtkOpenGLImageMapper::~vtkOpenGLImageMapper()
Ken Martin's avatar
Ken Martin committed
83 84 85 86
{
  this->Actor->UnRegister(this);
}

87 88 89 90 91 92 93 94
//----------------------------------------------------------------------------
// Release the graphics resources used by this texture.
void vtkOpenGLImageMapper::ReleaseGraphicsResources(vtkWindow *renWin)
{
  this->Actor->ReleaseGraphicsResources(renWin);
}


Ken Martin's avatar
Ken Martin committed
95 96 97 98 99 100 101 102 103 104

//----------------------------------------------------------------------------
// I know #define can be evil, but this macro absolutely ensures
// that the code will be inlined.  The macro expects 'val' to
// be predefined to the same type as y

#define vtkClampToUnsignedChar(x,y) \
{ \
  val = (y); \
  if (val < 0) \
105
  { \
Ken Martin's avatar
Ken Martin committed
106
    val = 0; \
107
  } \
Ken Martin's avatar
Ken Martin committed
108
  if (val > 255) \
109
  { \
Ken Martin's avatar
Ken Martin committed
110
    val = 255; \
111
  } \
Ken Martin's avatar
Ken Martin committed
112 113 114 115 116 117 118
  (x) = static_cast<unsigned char>(val); \
}
/* should do proper rounding, as follows:
  (x) = (unsigned char)(val + 0.5f); \
*/

// the bit-shift must be done after the comparison to zero
119
// because bit-shift is undefined behaviour for negative numbers
Ken Martin's avatar
Ken Martin committed
120 121 122 123
#define vtkClampIntToUnsignedChar(x,y,shift) \
{ \
  val = (y); \
  if (val < 0) \
124
  { \
Ken Martin's avatar
Ken Martin committed
125
    val = 0; \
126
  } \
127
  val >>= (shift); \
Ken Martin's avatar
Ken Martin committed
128
  if (val > 255) \
129
  { \
Ken Martin's avatar
Ken Martin committed
130
    val = 255; \
131
  } \
Ken Martin's avatar
Ken Martin committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
  (x) = static_cast<unsigned char>(val); \
}

// pad an integer to a multiply of four, for OpenGL
inline int vtkPadToFour(int n)
{
  return ((n+3)/4)*4;
}

//---------------------------------------------------------------
// render the image by doing the following:
// 1) apply shift and scale to pixel values
// 2) clamp to [0,255] and convert to unsigned char
// 3) draw using DrawPixels

template <class T>
148
void vtkOpenGLImageMapperRenderDouble(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
                                      T *dataPtr, double shift, double scale,
                                      vtkViewport *viewport)
{
  vtkOpenGLClearErrorMacro();

  int inMin0 = self->DisplayExtent[0];
  int inMax0 = self->DisplayExtent[1];
  int inMin1 = self->DisplayExtent[2];
  int inMax1 = self->DisplayExtent[3];

  int width = inMax0 - inMin0 + 1;
  int height = inMax1 - inMin1 + 1;

  vtkIdType* tempIncs = data->GetIncrements();
  vtkIdType inInc1 = tempIncs[1];

  int bpp = data->GetNumberOfScalarComponents();
  double range[2];
  data->GetPointData()->GetScalars()->GetDataTypeRange( range );

169
#ifdef GL_UNPACK_ALIGNMENT
Ken Martin's avatar
Ken Martin committed
170
  glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
171 172 173
#else
  assert("width must be a multiple of 4" && width ==4);
#endif
Ken Martin's avatar
Ken Martin committed
174 175 176 177 178 179 180 181 182 183 184

  // reformat data into unsigned char

  T *inPtr = dataPtr;
  T *inPtr1 = inPtr;

  int i;
  int j = height;

  unsigned char *newPtr;
  if (bpp < 4)
185
  {
Ken Martin's avatar
Ken Martin committed
186
    newPtr = new unsigned char[vtkPadToFour(3*width*height)];
187
  }
Ken Martin's avatar
Ken Martin committed
188
  else
189
  {
Ken Martin's avatar
Ken Martin committed
190
    newPtr = new unsigned char[4*width*height];
191
  }
Ken Martin's avatar
Ken Martin committed
192 193 194 195 196 197

  unsigned char *ptr = newPtr;
  double val;
  unsigned char tmp;

  while (--j >= 0)
198
  {
Ken Martin's avatar
Ken Martin committed
199 200 201
    inPtr = inPtr1;
    i = width;
    switch (bpp)
202
    {
Ken Martin's avatar
Ken Martin committed
203 204
      case 1:
        while (--i >= 0)
205
        {
Ken Martin's avatar
Ken Martin committed
206 207 208 209
          vtkClampToUnsignedChar(tmp,((*inPtr++ + shift)*scale));
          *ptr++ = tmp;
          *ptr++ = tmp;
          *ptr++ = tmp;
210
        }
Ken Martin's avatar
Ken Martin committed
211 212 213 214
        break;

      case 2:
        while (--i >= 0)
215
        {
Ken Martin's avatar
Ken Martin committed
216 217 218 219
          vtkClampToUnsignedChar(tmp,((*inPtr++ + shift)*scale));
          *ptr++ = tmp;
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
          *ptr++ = tmp;
220
        }
Ken Martin's avatar
Ken Martin committed
221 222 223 224
        break;

      case 3:
        while (--i >= 0)
225
        {
Ken Martin's avatar
Ken Martin committed
226 227 228
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
229
        }
Ken Martin's avatar
Ken Martin committed
230 231 232 233
        break;

      default:
        while (--i >= 0)
234
        {
Ken Martin's avatar
Ken Martin committed
235 236 237 238 239
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
          vtkClampToUnsignedChar(*ptr++,((*inPtr++ + shift)*scale));
          inPtr += bpp-4;
240
        }
Ken Martin's avatar
Ken Martin committed
241 242
        break;
    }
243 244
    inPtr1 += inInc1;
  }
Ken Martin's avatar
Ken Martin committed
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260

  self->DrawPixels(viewport, width, height, ((bpp < 4) ? 3 : 4),
                   static_cast<void *>(newPtr));

  delete [] newPtr;

 vtkOpenGLStaticCheckErrorMacro("failed after ImageMapperRenderDouble");
}

//---------------------------------------------------------------
// Same as above, but uses fixed-point math for shift and scale.
// The number of bits used for the fraction is determined from the
// scale.  Enough bits are always left over for the integer that
// overflow cannot occur.

template <class T>
261
void vtkOpenGLImageMapperRenderShort(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
262
                                     T *dataPtr, double shift, double scale,
Ken Martin's avatar
Ken Martin committed
263
                                     vtkViewport *viewport)
Ken Martin's avatar
Ken Martin committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
{
  vtkOpenGLClearErrorMacro();

  int inMin0 = self->DisplayExtent[0];
  int inMax0 = self->DisplayExtent[1];
  int inMin1 = self->DisplayExtent[2];
  int inMax1 = self->DisplayExtent[3];

  int width = inMax0 - inMin0 + 1;
  int height = inMax1 - inMin1 + 1;

  vtkIdType* tempIncs = data->GetIncrements();
  vtkIdType inInc1 = tempIncs[1];

  int bpp = data->GetNumberOfScalarComponents();

  double range[2];
  data->GetPointData()->GetScalars()->GetDataTypeRange( range );

283
#ifdef GL_UNPACK_ALIGNMENT
Ken Martin's avatar
Ken Martin committed
284
  glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
285 286 287
#else
  assert("width must be a multiple of 4" && width ==4);
#endif
Ken Martin's avatar
Ken Martin committed
288 289 290 291 292 293 294 295 296 297

  // Find the number of bits to use for the fraction:
  // continue increasing the bits until there is an overflow
  // in the worst case, then decrease by 1.
  // The "*2.0" and "*1.0" ensure that the comparison is done
  // with double-precision math.
  int bitShift = 0;
  double absScale = ((scale < 0) ? -scale : scale);

  while ((static_cast<long>(1 << bitShift)*absScale)*2.0*USHRT_MAX < INT_MAX*1.0)
298
  {
Ken Martin's avatar
Ken Martin committed
299
    bitShift++;
300
  }
Ken Martin's avatar
Ken Martin committed
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
  bitShift--;

  long sscale = static_cast<long>(scale*(1 << bitShift));
  long sshift = static_cast<long>(sscale*shift);
  /* should do proper rounding, as follows:
  long sscale = (long) floor(scale*(1 << bitShift) + 0.5);
  long sshift = (long) floor((scale*shift + 0.5)*(1 << bitShift));
  */
  long val;
  unsigned char tmp;

  T *inPtr = dataPtr;
  T *inPtr1 = inPtr;

  int i;
  int j = height;

  unsigned char *newPtr;
  if (bpp < 4)
320
  {
Ken Martin's avatar
Ken Martin committed
321
    newPtr = new unsigned char[vtkPadToFour(3*width*height)];
322
  }
Ken Martin's avatar
Ken Martin committed
323
  else
324
  {
Ken Martin's avatar
Ken Martin committed
325
    newPtr = new unsigned char[4*width*height];
326
  }
Ken Martin's avatar
Ken Martin committed
327 328 329 330

  unsigned char *ptr = newPtr;

  while (--j >= 0)
331
  {
Ken Martin's avatar
Ken Martin committed
332 333 334 335
    inPtr = inPtr1;
    i = width;

    switch (bpp)
336
    {
Ken Martin's avatar
Ken Martin committed
337 338
      case 1:
        while (--i >= 0)
339
        {
Ken Martin's avatar
Ken Martin committed
340 341 342 343
          vtkClampIntToUnsignedChar(tmp,(*inPtr++*sscale+sshift),bitShift);
          *ptr++ = tmp;
          *ptr++ = tmp;
          *ptr++ = tmp;
344
        }
Ken Martin's avatar
Ken Martin committed
345 346 347 348
        break;

      case 2:
        while (--i >= 0)
349
        {
Ken Martin's avatar
Ken Martin committed
350 351 352 353
          vtkClampIntToUnsignedChar(tmp,(*inPtr++*sscale+sshift),bitShift);
          *ptr++ = tmp;
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
          *ptr++ = tmp;
354
        }
Ken Martin's avatar
Ken Martin committed
355 356 357 358
        break;

      case 3:
        while (--i >= 0)
359
        {
Ken Martin's avatar
Ken Martin committed
360 361 362
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
363
        }
Ken Martin's avatar
Ken Martin committed
364 365 366 367
        break;

      default:
        while (--i >= 0)
368
        {
Ken Martin's avatar
Ken Martin committed
369 370 371 372 373
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
          vtkClampIntToUnsignedChar(*ptr++,(*inPtr++*sscale+sshift),bitShift);
          inPtr += bpp-4;
374
        }
Ken Martin's avatar
Ken Martin committed
375 376
        break;
    }
377 378
    inPtr1 += inInc1;
  }
Ken Martin's avatar
Ken Martin committed
379 380 381 382 383 384 385 386 387 388 389 390 391

  self->DrawPixels(viewport, width, height, ((bpp < 4) ? 3 : 4),
                   static_cast<void *>(newPtr));

  delete [] newPtr;

  vtkOpenGLStaticCheckErrorMacro("failed after ImageMapperRenderShort");
}

//---------------------------------------------------------------
// render unsigned char data without any shift/scale

template <class T>
392
void vtkOpenGLImageMapperRenderChar(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
393
                                    T *dataPtr, vtkViewport *viewport)
Ken Martin's avatar
Ken Martin committed
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
{
  vtkOpenGLClearErrorMacro();

  int inMin0 = self->DisplayExtent[0];
  int inMax0 = self->DisplayExtent[1];
  int inMin1 = self->DisplayExtent[2];
  int inMax1 = self->DisplayExtent[3];

  int width = inMax0 - inMin0 + 1;
  int height = inMax1 - inMin1 + 1;

  vtkIdType* tempIncs = data->GetIncrements();
  vtkIdType inInc1 = tempIncs[1];

  int bpp = data->GetPointData()->GetScalars()->GetNumberOfComponents();

  double range[2];
  data->GetPointData()->GetScalars()->GetDataTypeRange( range );

413
#ifdef GL_UNPACK_ALIGNMENT
Ken Martin's avatar
Ken Martin committed
414
  glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
415 416 417
#else
  assert("width must be a multiple of 4" && width ==4);
#endif
Ken Martin's avatar
Ken Martin committed
418 419

  //
420
#ifdef GL_UNPACK_ROW_LENGTH
Ken Martin's avatar
Ken Martin committed
421
  if (bpp == 3)
422
  { // feed through RGB bytes without reformatting
Ken Martin's avatar
Ken Martin committed
423
    if (inInc1 != width*bpp)
424
    {
Ken Martin's avatar
Ken Martin committed
425
      glPixelStorei( GL_UNPACK_ROW_LENGTH, inInc1/bpp );
426
    }
Ken Martin's avatar
Ken Martin committed
427 428
    self->DrawPixels(viewport, width, height, 3,
                 static_cast<void *>(dataPtr));
429
  }
Ken Martin's avatar
Ken Martin committed
430
  else if (bpp == 4)
431
  { // feed through RGBA bytes without reformatting
Ken Martin's avatar
Ken Martin committed
432
    if (inInc1 != width*bpp)
433
    {
Ken Martin's avatar
Ken Martin committed
434
      glPixelStorei( GL_UNPACK_ROW_LENGTH, inInc1/bpp );
435
    }
Ken Martin's avatar
Ken Martin committed
436 437
    self->DrawPixels(viewport, width, height, 4,
                     static_cast<void *>(dataPtr));
438
  }
Ken Martin's avatar
Ken Martin committed
439
  else
440
#endif
441
  { // feed through other bytes without reformatting
Ken Martin's avatar
Ken Martin committed
442 443 444 445 446 447 448 449 450
    T *inPtr = dataPtr;
    T *inPtr1 = inPtr;
    unsigned char tmp;

    int i;
    int j = height;

    unsigned char *newPtr;
    if (bpp < 4)
451
    {
Ken Martin's avatar
Ken Martin committed
452
      newPtr = new unsigned char[vtkPadToFour(3*width*height)];
453
    }
Ken Martin's avatar
Ken Martin committed
454
    else
455
    {
Ken Martin's avatar
Ken Martin committed
456
      newPtr = new unsigned char[4*width*height];
457
    }
Ken Martin's avatar
Ken Martin committed
458 459 460 461

    unsigned char *ptr = newPtr;

    while (--j >= 0)
462
    {
Ken Martin's avatar
Ken Martin committed
463 464 465 466
      inPtr = inPtr1;
      i = width;

      switch (bpp)
467
      {
Ken Martin's avatar
Ken Martin committed
468 469
        case 1:
          while (--i >= 0)
470
          {
Ken Martin's avatar
Ken Martin committed
471 472 473
            *ptr++ = tmp = *inPtr++;
            *ptr++ = tmp;
            *ptr++ = tmp;
474
          }
Ken Martin's avatar
Ken Martin committed
475 476 477 478
          break;

        case 2:
          while (--i >= 0)
479
          {
Ken Martin's avatar
Ken Martin committed
480 481 482
            *ptr++ = tmp = *inPtr++;
            *ptr++ = *inPtr++;
            *ptr++ = tmp;
483
          }
Ken Martin's avatar
Ken Martin committed
484 485 486 487
          break;

        case 3:
          while (--i >= 0)
488
          {
Ken Martin's avatar
Ken Martin committed
489 490 491
            *ptr++ = *inPtr++;
            *ptr++ = *inPtr++;
            *ptr++ = *inPtr++;
492
          }
Ken Martin's avatar
Ken Martin committed
493 494 495 496
          break;

        default:
          while (--i >= 0)
497
          {
Ken Martin's avatar
Ken Martin committed
498 499 500 501 502
            *ptr++ = *inPtr++;
            *ptr++ = *inPtr++;
            *ptr++ = *inPtr++;
            *ptr++ = *inPtr++;
            inPtr += bpp-4;
503
          }
Ken Martin's avatar
Ken Martin committed
504 505
          break;
      }
506 507
      inPtr1 += inInc1;
    }
Ken Martin's avatar
Ken Martin committed
508 509 510 511

    self->DrawPixels(viewport, width, height, ((bpp < 4) ? 3 : 4), static_cast<void *>(newPtr));

    delete [] newPtr;
512
  }
Ken Martin's avatar
Ken Martin committed
513

514
#ifdef GL_UNPACK_ROW_LENGTH
Ken Martin's avatar
Ken Martin committed
515
  glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
516
#endif
Ken Martin's avatar
Ken Martin committed
517 518 519 520 521 522 523 524 525 526 527 528 529 530

  vtkOpenGLStaticCheckErrorMacro("failed after ImageMapperRenderChar");
}

//----------------------------------------------------------------------------
// Define overloads to help the template macro below dispatch to a
// suitable implementation for each type.  The last argument is of
// type "long" for the template and of type "int" for the
// non-templates.  The template macro's call to this function always
// passes a literal "1" as the last argument, which requires a
// conversion to produce a long.  This helps broken compilers select
// the non-template even when the template is otherwise an equal
// match.
template <class T>
531
void vtkOpenGLImageMapperRender(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
532 533 534
                                T *dataPtr, double shift, double scale,
                                vtkViewport *viewport)
{
Ken Martin's avatar
Ken Martin committed
535
  vtkOpenGLImageMapperRenderDouble(self, data, dataPtr, shift, scale, viewport);
Ken Martin's avatar
Ken Martin committed
536 537
}

538
static void vtkOpenGLImageMapperRender(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
539 540 541 542
                                       char* dataPtr, double shift, double scale,
                                       vtkViewport *viewport)
{
  if(shift == 0.0 && scale == 1.0)
543
  {
Ken Martin's avatar
Ken Martin committed
544
    vtkOpenGLImageMapperRenderChar(self, data, dataPtr, viewport);
545
  }
Ken Martin's avatar
Ken Martin committed
546
  else
547
  {
Ken Martin's avatar
Ken Martin committed
548
    vtkOpenGLImageMapperRenderShort(self, data, dataPtr, shift, scale, viewport);
549
  }
Ken Martin's avatar
Ken Martin committed
550 551
}

552
static void vtkOpenGLImageMapperRender(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
553 554 555 556
                                       unsigned char* dataPtr, double shift, double scale,
                                       vtkViewport *viewport)
{
  if(shift == 0.0 && scale == 1.0)
557
  {
Ken Martin's avatar
Ken Martin committed
558
    vtkOpenGLImageMapperRenderChar(self, data, dataPtr, viewport);
559
  }
Ken Martin's avatar
Ken Martin committed
560
  else
561
  {
Ken Martin's avatar
Ken Martin committed
562
    vtkOpenGLImageMapperRenderShort(self, data, dataPtr, shift, scale, viewport);
563
  }
Ken Martin's avatar
Ken Martin committed
564 565
}

566
static void vtkOpenGLImageMapperRender(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
567 568 569 570
                                       signed char* dataPtr, double shift, double scale,
                                       vtkViewport *viewport)
{
  if(shift == 0.0 && scale == 1.0)
571
  {
Ken Martin's avatar
Ken Martin committed
572
    vtkOpenGLImageMapperRenderChar(self, data, dataPtr, viewport);
573
  }
Ken Martin's avatar
Ken Martin committed
574
  else
575
  {
Ken Martin's avatar
Ken Martin committed
576
    vtkOpenGLImageMapperRenderShort(self, data, dataPtr, shift, scale, viewport);
577
  }
Ken Martin's avatar
Ken Martin committed
578 579
}

580
static void vtkOpenGLImageMapperRender(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
581 582 583
                                       short* dataPtr, double shift, double scale,
                                       vtkViewport *viewport)
{
Ken Martin's avatar
Ken Martin committed
584
  vtkOpenGLImageMapperRenderShort(self, data, dataPtr, shift, scale, viewport);
Ken Martin's avatar
Ken Martin committed
585 586
}

587
static void vtkOpenGLImageMapperRender(vtkOpenGLImageMapper *self, vtkImageData *data,
Ken Martin's avatar
Ken Martin committed
588 589 590
                                       unsigned short* dataPtr, double shift, double scale,
                                       vtkViewport *viewport)
{
Ken Martin's avatar
Ken Martin committed
591
  vtkOpenGLImageMapperRenderShort(self, data, dataPtr, shift, scale, viewport);
Ken Martin's avatar
Ken Martin committed
592 593 594 595 596
}

//----------------------------------------------------------------------------
// Expects data to be X, Y, components

597
void vtkOpenGLImageMapper::RenderData(vtkViewport* viewport,
Ken Martin's avatar
Ken Martin committed
598 599 600 601 602 603 604
                                      vtkImageData *data, vtkActor2D *actor)
{
  void *ptr0;
  double shift, scale;

  vtkWindow* window = static_cast<vtkWindow *>(viewport->GetVTKWindow());
  if (!window)
605
  {
606
    vtkErrorMacro (<<"vtkOpenGLImageMapper::RenderData - no window set for viewport");
Ken Martin's avatar
Ken Martin committed
607
    return;
608
  }
Ken Martin's avatar
Ken Martin committed
609

610 611 612

  this->Actor->SetProperty(actor->GetProperty());

Ken Martin's avatar
Ken Martin committed
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
  // Make this window current. May have become not current due to
  // data updates since the render started.
  window->MakeCurrent();

  vtkOpenGLClearErrorMacro();

  shift = this->GetColorShift();
  scale = this->GetColorScale();

  ptr0 = data->GetScalarPointer(this->DisplayExtent[0],
                                this->DisplayExtent[2],
                                this->DisplayExtent[4]);

  // Get the position of the image actor
  int* actorPos =
    actor->GetActualPositionCoordinate()->GetComputedViewportValue(viewport);
  // negative positions will already be clipped to viewport
  actorPos[0] += this->PositionAdjustment[0];
  actorPos[1] += this->PositionAdjustment[1];

Ken Martin's avatar
Ken Martin committed
633
  this->Actor->SetPosition(actorPos[0], actorPos[1]);
Ken Martin's avatar
Ken Martin committed
634 635 636
  this->Actor->SetPosition2(actor->GetPosition2());

  switch (data->GetPointData()->GetScalars()->GetDataType())
637
  {
Ken Martin's avatar
Ken Martin committed
638
    vtkTemplateMacro(
639
      vtkOpenGLImageMapperRender(this, data, static_cast<VTK_TT*>(ptr0),
Ken Martin's avatar
Ken Martin committed
640
                                 shift, scale, viewport)
Ken Martin's avatar
Ken Martin committed
641 642 643
      );
    default:
      vtkErrorMacro ( << "Unsupported image type: " << data->GetScalarType());
644
  }
Ken Martin's avatar
Ken Martin committed
645 646 647 648 649 650

  vtkOpenGLCheckErrorMacro("failed after RenderData");
}



651
void vtkOpenGLImageMapper::DrawPixels(vtkViewport *viewport, int width, int height, int numComponents, void *data)
Ken Martin's avatar
Ken Martin committed
652 653 654 655 656 657 658 659 660
{
  int* actorPos =
    this->Actor->GetActualPositionCoordinate()->GetComputedViewportValue(viewport);
  int* actorPos2 =
    this->Actor->GetActualPosition2Coordinate()->GetComputedViewportValue(viewport);

  float xscale = 1.0;
  float yscale = 1.0;
  if (this->GetRenderToRectangle())
661
  {
Ken Martin's avatar
Ken Martin committed
662 663
    int rectwidth  = (actorPos2[0] - actorPos[0]) + 1;
    int rectheight = (actorPos2[1] - actorPos[1]) + 1;
664 665
    xscale = static_cast<float>(rectwidth)/width;
    yscale = static_cast<float>(rectheight)/height;
666
  }
Ken Martin's avatar
Ken Martin committed
667 668 669

  vtkPolyData *pd = vtkPolyDataMapper2D::SafeDownCast(this->Actor->GetMapper())->GetInput();
  vtkPoints *points = pd->GetPoints();
Ken Martin's avatar
Ken Martin committed
670 671 672 673
  points->SetPoint(0, 0.0, 0.0, 0);
  points->SetPoint(1, width*xscale, 0.0, 0);
  points->SetPoint(2, width*xscale, height*yscale, 0);
  points->SetPoint(3, 0.0, height*yscale, 0);
Ken Martin's avatar
Ken Martin committed
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692

  vtkDataArray *tcoords = pd->GetPointData()->GetTCoords();
  float tmp[2];
  tmp[0] = 0;
  tmp[1] = 0;
  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);

  vtkImageData *id = vtkImageData::New();
  id->SetExtent(0,width-1, 0,height-1, 0,0);
  vtkUnsignedCharArray *uca = vtkUnsignedCharArray::New();
  uca->SetNumberOfComponents(numComponents);
  uca->SetArray((unsigned char *)data,width*height*numComponents,true);
  id->GetPointData()->SetScalars(uca);
693
  uca->Delete();
Ken Martin's avatar
Ken Martin committed
694 695 696 697

  this->Actor->GetTexture()->SetInputData(id);

  this->Actor->RenderOverlay(viewport);
698
  id->Delete();
Ken Martin's avatar
Ken Martin committed
699 700 701
}


702
void vtkOpenGLImageMapper::PrintSelf(ostream& os, vtkIndent indent)
Ken Martin's avatar
Ken Martin committed
703 704 705
{
  this->Superclass::PrintSelf(os,indent);
}