Salome HOME
eb82eedfc9d803f7c366560f07adfd3164ae63c9
[modules/gui.git] / src / VTKViewer / VTKViewer_Texture.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "VTKViewer_Texture.h"
23
24 #include "vtkHomogeneousTransform.h"
25 #include "vtkImageData.h"
26 #include "vtkLookupTable.h"
27 #include "vtkObjectFactory.h"
28 #include "vtkOpenGLRenderer.h"
29 #include "vtkPointData.h"
30 #include "vtkRenderWindow.h"
31 #ifndef VTK_OPENGL2
32 #include "vtkOpenGLExtensionManager.h"
33 #include "vtkgl.h" // vtkgl namespace
34 #else
35 #include "vtkTextureObject.h"
36 #include "vtkOpenGLError.h"
37 #endif
38 #include "vtkOpenGLRenderWindow.h"
39 #include "vtkTransform.h"
40 #include "vtkPixelBufferObject.h"
41 #include "vtk_glew.h"
42 #include <vtkObjectFactory.h>
43
44 vtkStandardNewMacro(VTKViewer_Texture)
45
46
47 // ----------------------------------------------------------------------------
48 VTKViewer_Texture::VTKViewer_Texture()
49 {
50   myWidth = 0;
51   myHeight = 0;
52   myPosition = VTKViewer_Texture::Centered;
53 }
54
55 // ----------------------------------------------------------------------------
56 VTKViewer_Texture::~VTKViewer_Texture()
57 {
58 }
59
60 // ----------------------------------------------------------------------------
61 // Implement base class method.
62 void VTKViewer_Texture::Load(vtkRenderer *ren)
63 {
64 #ifndef VTK_OPENGL2  
65   GLenum format = GL_LUMINANCE;
66   vtkImageData *input = this->GetInput();
67
68   this->Initialize(ren);
69
70   // Need to reload the texture.
71   // There used to be a check on the render window's mtime, but
72   // this is too broad of a check (e.g. it would cause all textures
73   // to load when only the desired update rate changed).
74   // If a better check is required, check something more specific,
75   // like the graphics context.
76   vtkOpenGLRenderWindow* renWin = 
77     static_cast<vtkOpenGLRenderWindow*>(ren->GetRenderWindow());
78
79   if(this->BlendingMode != VTK_TEXTURE_BLENDING_MODE_NONE
80      && vtkgl::ActiveTexture)
81     {
82     glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, vtkgl::COMBINE);
83
84     switch(this->BlendingMode)
85       {
86       case VTK_TEXTURE_BLENDING_MODE_REPLACE:
87         {
88         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_REPLACE);
89         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_REPLACE);
90         break;
91         }
92       case VTK_TEXTURE_BLENDING_MODE_MODULATE:
93         {
94         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_MODULATE);
95         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_MODULATE);
96         break;
97         }
98       case VTK_TEXTURE_BLENDING_MODE_ADD:
99         {
100         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_ADD);
101         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_ADD);
102         break;
103         }
104       case VTK_TEXTURE_BLENDING_MODE_ADD_SIGNED:
105         {
106         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, vtkgl::ADD_SIGNED);
107         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, vtkgl::ADD_SIGNED);
108         break;
109         }
110       case VTK_TEXTURE_BLENDING_MODE_INTERPOLATE:
111         {
112         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, vtkgl::INTERPOLATE);
113         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, vtkgl::INTERPOLATE);
114         break;
115         }
116       case VTK_TEXTURE_BLENDING_MODE_SUBTRACT:
117         {
118         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, vtkgl::SUBTRACT);
119         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, vtkgl::SUBTRACT);
120         break;
121         }
122       default:
123         {
124         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_ADD);
125         glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_ADD);
126         }
127       }
128     }
129
130   if (this->GetMTime() > this->LoadTime.GetMTime() ||
131       input->GetMTime() > this->LoadTime.GetMTime() ||
132       (this->GetLookupTable() && this->GetLookupTable()->GetMTime () >  
133        this->LoadTime.GetMTime()) || 
134        renWin != this->RenderWindow.GetPointer() ||
135        renWin->GetContextCreationTime() > this->LoadTime)
136     {
137     int bytesPerPixel;
138     int size[3];
139     vtkDataArray *scalars;
140     unsigned char *dataPtr;
141     unsigned char *resultData=NULL;
142     int xsize, ysize;
143     unsigned int xs,ys;
144     GLuint tempIndex=0;
145
146     // Get the scalars the user choose to color with.
147     scalars = this->GetInputArrayToProcess(0, input);
148
149     // make sure scalars are non null
150     if (!scalars) 
151       {
152       vtkErrorMacro(<< "No scalar values found for texture input!");
153       return;
154       }
155
156     // get some info
157     input->GetDimensions(size);
158
159     if (input->GetNumberOfCells() == scalars->GetNumberOfTuples())
160       {
161       // we are using cell scalars. Adjust image size for cells.
162       for (int kk=0; kk < 3; kk++)
163         {
164         if (size[kk]>1)
165           {
166           size[kk]--;
167           }
168         }
169       }
170
171     bytesPerPixel = scalars->GetNumberOfComponents();
172
173     // make sure using unsigned char data of color scalars type
174     if (this->MapColorScalarsThroughLookupTable ||
175        scalars->GetDataType() != VTK_UNSIGNED_CHAR )
176       {
177       dataPtr = this->MapScalarsToColors (scalars);
178       bytesPerPixel = 4;
179       }
180     else
181       {
182       dataPtr = static_cast<vtkUnsignedCharArray *>(scalars)->GetPointer(0);
183       }
184
185     // we only support 2d texture maps right now
186     // so one of the three sizes must be 1, but it 
187     // could be any of them, so lets find it
188     if (size[0] == 1)
189       {
190       xsize = size[1]; ysize = size[2];
191       }
192     else
193       {
194       xsize = size[0];
195       if (size[1] == 1)
196         {
197         ysize = size[2];
198         }
199       else
200         {
201         ysize = size[1];
202         if (size[2] != 1)
203           {
204           vtkErrorMacro(<< "3D texture maps currently are not supported!");
205           return;
206           }
207         }
208       }
209     
210     
211     if(!this->CheckedHardwareSupport)
212       {
213       vtkOpenGLExtensionManager *m=renWin->GetExtensionManager();
214       this->CheckedHardwareSupport=true;
215       this->SupportsNonPowerOfTwoTextures=
216         m->ExtensionSupported("GL_VERSION_2_0")
217         || m->ExtensionSupported("GL_ARB_texture_non_power_of_two");
218       this->SupportsPBO=vtkPixelBufferObject::IsSupported(renWin);
219       }
220     
221     // -- decide whether the texture needs to be resampled --
222     
223     GLint maxDimGL;
224     glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxDimGL);
225     // if larger than permitted by the graphics library then must resample
226     bool resampleNeeded=xsize > maxDimGL || ysize > maxDimGL;
227     if(resampleNeeded)
228       {
229       vtkDebugMacro( "Texture too big for gl, maximum is " << maxDimGL);
230       }
231     
232     if(!resampleNeeded && !this->SupportsNonPowerOfTwoTextures)
233       {
234       // xsize and ysize must be a power of 2 in OpenGL
235       xs = static_cast<unsigned int>(xsize);
236       ys = static_cast<unsigned int>(ysize);
237       while (!(xs & 0x01))
238         {
239         xs = xs >> 1;
240         }
241       while (!(ys & 0x01))
242         {
243         ys = ys >> 1;
244         }
245       // if not a power of two then resampling is required
246       resampleNeeded= (xs>1) || (ys>1);
247       }
248
249     if(resampleNeeded)
250       {
251       vtkDebugMacro(<< "Resampling texture to power of two for OpenGL");
252       resultData = this->ResampleToPowerOfTwo(xsize, ysize, dataPtr, 
253                                               bytesPerPixel);
254       }
255
256     if ( resultData == NULL )
257         {
258         resultData = dataPtr;
259         }
260
261     // free any old display lists (from the old context)
262     if (this->RenderWindow)
263       {
264       this->ReleaseGraphicsResources(this->RenderWindow);
265       }
266     
267      this->RenderWindow = ren->GetRenderWindow();
268      
269     // make the new context current before we mess with opengl
270     this->RenderWindow->MakeCurrent();
271  
272     // define a display list for this texture
273     // get a unique display list id
274
275 #ifdef GL_VERSION_1_1
276     glGenTextures(1, &tempIndex);
277     this->Index = static_cast<long>(tempIndex);
278     glBindTexture(GL_TEXTURE_2D, this->Index);
279 #else
280     this->Index = glGenLists(1);
281     glDeleteLists (static_cast<GLuint>(this->Index), static_cast<GLsizei>(0));
282     glNewList (static_cast<GLuint>(this->Index), GL_COMPILE);
283 #endif
284     //seg fault protection for those wackos that don't use an
285     //opengl render window
286     if(this->RenderWindow->IsA("vtkOpenGLRenderWindow"))
287       {
288       static_cast<vtkOpenGLRenderWindow *>(ren->GetRenderWindow())->
289         RegisterTextureResource( this->Index );
290       }
291
292     if (this->Interpolate)
293       {
294       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
295                        GL_LINEAR);
296       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
297                        GL_LINEAR );
298       }
299     else
300       {
301       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
302       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
303       }
304     if (this->Repeat)
305       {
306       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_REPEAT );
307       glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_REPEAT );
308       }
309     else
310       {
311       vtkOpenGLExtensionManager* manager = renWin->GetExtensionManager();
312       if (this->EdgeClamp &&
313            (manager->ExtensionSupported("GL_VERSION_1_2") ||
314             manager->ExtensionSupported("GL_EXT_texture_edge_clamp")))
315         {
316         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
317                          vtkgl::CLAMP_TO_EDGE );
318         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
319                          vtkgl::CLAMP_TO_EDGE );
320         }
321       else
322         {
323         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP );
324         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP );
325         }
326       }
327     int internalFormat = bytesPerPixel;
328     switch (bytesPerPixel)
329       {
330       case 1: format = GL_LUMINANCE; break;
331       case 2: format = GL_LUMINANCE_ALPHA; break;
332       case 3: format = GL_RGB; break;
333       case 4: format = GL_RGBA; break;
334       }
335     // if we are using OpenGL 1.1, you can force 32 or16 bit textures
336 #ifdef GL_VERSION_1_1
337     if (this->Quality == VTK_TEXTURE_QUALITY_32BIT)
338       {
339       switch (bytesPerPixel)
340         {
341         case 1: internalFormat = GL_LUMINANCE8; break;
342         case 2: internalFormat = GL_LUMINANCE8_ALPHA8; break;
343         case 3: internalFormat = GL_RGB8; break;
344         case 4: internalFormat = GL_RGBA8; break;
345         }
346       }
347     else if (this->Quality == VTK_TEXTURE_QUALITY_16BIT)
348       {
349       switch (bytesPerPixel)
350         {
351         case 1: internalFormat = GL_LUMINANCE4; break;
352         case 2: internalFormat = GL_LUMINANCE4_ALPHA4; break;
353         case 3: internalFormat = GL_RGB4; break;
354         case 4: internalFormat = GL_RGBA4; break;
355         }
356       }
357 #endif
358     if(this->SupportsPBO)
359       {
360       if(this->PBO==0)
361         {
362         this->PBO=vtkPixelBufferObject::New();
363         this->PBO->SetContext(renWin);
364         }
365       unsigned int dims[2];
366       vtkIdType increments[2];
367       dims[0]=static_cast<unsigned int>(xsize);
368       dims[1]=static_cast<unsigned int>(ysize);
369       increments[0]=0;
370       increments[1]=0;
371       this->PBO->Upload2D(VTK_UNSIGNED_CHAR,resultData,dims,bytesPerPixel,
372         increments);
373       // non-blocking call
374       this->PBO->Bind(vtkPixelBufferObject::UNPACKED_BUFFER);
375       glTexImage2D( GL_TEXTURE_2D, 0 , internalFormat,
376                     xsize, ysize, 0, format, 
377                     GL_UNSIGNED_BYTE,0);
378       myWidth = xsize;
379       myHeight = ysize;
380       this->PBO->UnBind();
381       }
382     else
383       {
384       // blocking call
385       glTexImage2D( GL_TEXTURE_2D, 0 , internalFormat,
386                     xsize, ysize, 0, format, 
387                     GL_UNSIGNED_BYTE,
388                     static_cast<const GLvoid *>(resultData) );
389         myWidth = xsize;
390         myHeight = ysize;
391       }
392 #ifndef GL_VERSION_1_1
393     glEndList ();
394 #endif
395     // modify the load time to the current time
396     this->LoadTime.Modified();
397     
398     // free memory
399     if (resultData != dataPtr)
400       {
401       delete [] resultData;
402       }
403     }
404
405   // execute the display list that uses creates the texture
406 #ifdef GL_VERSION_1_1
407   glBindTexture(GL_TEXTURE_2D, this->Index);
408 #else
409   glCallList(this->Index);
410 #endif
411   
412   // don't accept fragments if they have zero opacity. this will stop the
413   // zbuffer from be blocked by totally transparent texture fragments.
414   glAlphaFunc (GL_GREATER, static_cast<GLclampf>(0));
415   glEnable (GL_ALPHA_TEST);
416
417   if (this->PremultipliedAlpha)
418     {
419     // save the blend function.
420     glPushAttrib(GL_COLOR_BUFFER_BIT);
421
422     // make the blend function correct for textures premultiplied by alpha.
423     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
424     }
425
426   // now bind it
427   glEnable(GL_TEXTURE_2D);
428
429   // clear any texture transform
430   glMatrixMode(GL_TEXTURE);
431   glLoadIdentity();
432
433   // build transformation 
434   if (this->Transform)
435     {
436     double *mat = this->Transform->GetMatrix()->Element[0];
437     double mat2[16];
438     mat2[0] = mat[0];
439     mat2[1] = mat[4];
440     mat2[2] = mat[8];
441     mat2[3] = mat[12];
442     mat2[4] = mat[1];
443     mat2[5] = mat[5];
444     mat2[6] = mat[9];
445     mat2[7] = mat[13];
446     mat2[8] = mat[2];
447     mat2[9] = mat[6];
448     mat2[10] = mat[10];
449     mat2[11] = mat[14];
450     mat2[12] = mat[3];
451     mat2[13] = mat[7];
452     mat2[14] = mat[11];
453     mat2[15] = mat[15];
454     
455     // insert texture transformation 
456     glMultMatrixd(mat2);
457     }
458   glMatrixMode(GL_MODELVIEW);
459   
460   GLint uUseTexture=-1;
461   GLint uTexture=-1;
462   
463   vtkOpenGLRenderer *oRenderer=static_cast<vtkOpenGLRenderer *>(ren);
464  
465 /*  if(oRenderer->GetDepthPeelingHigherLayer())
466     {
467     uUseTexture=oRenderer->GetUseTextureUniformVariable();
468     uTexture=oRenderer->GetTextureUniformVariable();
469     vtkgl::Uniform1i(uUseTexture,1);
470     vtkgl::Uniform1i(uTexture,0); // active texture 0
471     }
472     */
473 #else
474     if (!this->ExternalTextureObject)
475     {
476     vtkImageData *input = this->GetInput();
477
478     // Need to reload the texture.
479     // There used to be a check on the render window's mtime, but
480     // this is too broad of a check (e.g. it would cause all textures
481     // to load when only the desired update rate changed).
482     // If a better check is required, check something more specific,
483     // like the graphics context.
484     vtkOpenGLRenderWindow* renWin =
485       static_cast<vtkOpenGLRenderWindow*>(ren->GetRenderWindow());
486
487     // has something changed so that we need to rebuild the texture?
488     if (this->GetMTime() > this->LoadTime.GetMTime() ||
489         input->GetMTime() > this->LoadTime.GetMTime() ||
490         (this->GetLookupTable() && this->GetLookupTable()->GetMTime () >
491          this->LoadTime.GetMTime()) ||
492          renWin != this->RenderWindow.GetPointer() ||
493          renWin->GetContextCreationTime() > this->LoadTime)
494       {
495       int size[3];
496       unsigned char *dataPtr;
497       unsigned char *resultData = 0;
498       int xsize, ysize;
499
500       this->RenderWindow = renWin;
501       if (this->TextureObject == 0)
502         {
503         this->TextureObject = vtkTextureObject::New();
504         }
505       this->TextureObject->ResetFormatAndType();
506       this->TextureObject->SetContext(renWin);
507
508       // Get the scalars the user choose to color with.
509       vtkDataArray* scalars = this->GetInputArrayToProcess(0, input);
510
511       // make sure scalars are non null
512       if (!scalars)
513         {
514         vtkErrorMacro(<< "No scalar values found for texture input!");
515         return;
516         }
517
518       // get some info
519       input->GetDimensions(size);
520
521       if (input->GetNumberOfCells() == scalars->GetNumberOfTuples())
522         {
523         // we are using cell scalars. Adjust image size for cells.
524         for (int kk = 0; kk < 3; kk++)
525           {
526           if (size[kk]>1)
527             {
528             size[kk]--;
529             }
530           }
531         }
532
533       int bytesPerPixel = scalars->GetNumberOfComponents();
534
535       // make sure using unsigned char data of color scalars type
536       if (this->IsDepthTexture != 1 &&
537         (this->ColorMode ||
538          scalars->GetDataType() != VTK_UNSIGNED_CHAR ))
539         {
540         dataPtr = this->MapScalarsToColors (scalars);
541         bytesPerPixel = 4;
542         }
543       else
544         {
545         dataPtr = static_cast<vtkUnsignedCharArray *>(scalars)->GetPointer(0);
546         }
547
548       // we only support 2d texture maps right now
549       // so one of the three sizes must be 1, but it
550       // could be any of them, so lets find it
551       if (size[0] == 1)
552         {
553         xsize = size[1]; ysize = size[2];
554         }
555       else
556         {
557         xsize = size[0];
558         if (size[1] == 1)
559           {
560           ysize = size[2];
561           }
562         else
563           {
564           ysize = size[1];
565           if (size[2] != 1)
566             {
567             vtkErrorMacro(<< "3D texture maps currently are not supported!");
568             return;
569             }
570           }
571         }
572
573       // -- decide whether the texture needs to be resampled --
574       GLint maxDimGL;
575       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxDimGL);
576       vtkOpenGLCheckErrorMacro("failed at glGetIntegerv");
577       // if larger than permitted by the graphics library then must resample
578       bool resampleNeeded = xsize > maxDimGL || ysize > maxDimGL;
579       if(resampleNeeded)
580         {
581         vtkDebugMacro( "Texture too big for gl, maximum is " << maxDimGL);
582         }
583
584       if (resampleNeeded)
585         {
586           //ostate->vtkglGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxDimGL);
587           vtkDebugMacro(<< "Resampling texture to power of two for OpenGL");
588           resultData = this->ResampleToPowerOfTwo(xsize, ysize, dataPtr,
589                                                   bytesPerPixel, maxDimGL);
590         }
591
592       if (!resultData)
593         {
594         resultData = dataPtr;
595         }
596
597       // create the texture
598       if (this->IsDepthTexture)
599         {
600         this->TextureObject->CreateDepthFromRaw(
601           xsize, ysize, vtkTextureObject::Float32, scalars->GetDataType(), resultData);
602         }
603       else
604         {
605         this->TextureObject->Create2DFromRaw(
606           xsize, ysize, bytesPerPixel, VTK_UNSIGNED_CHAR, resultData);
607         }
608       myWidth = xsize;
609       myHeight = ysize;
610       // activate a free texture unit for this texture
611       this->TextureObject->Activate();
612
613       // update parameters
614       if (this->Interpolate)
615         {
616         this->TextureObject->SetMinificationFilter(vtkTextureObject::Linear);
617         this->TextureObject->SetMagnificationFilter(vtkTextureObject::Linear);
618         }
619       else
620         {
621         this->TextureObject->SetMinificationFilter(vtkTextureObject::Nearest);
622         this->TextureObject->SetMagnificationFilter(vtkTextureObject::Nearest);
623         }
624       if (this->Repeat)
625         {
626         this->TextureObject->SetWrapS(vtkTextureObject::Repeat);
627         this->TextureObject->SetWrapT(vtkTextureObject::Repeat);
628         this->TextureObject->SetWrapR(vtkTextureObject::Repeat);
629         }
630       else
631         {
632         this->TextureObject->SetWrapS(vtkTextureObject::ClampToEdge);
633         this->TextureObject->SetWrapT(vtkTextureObject::ClampToEdge);
634         this->TextureObject->SetWrapR(vtkTextureObject::ClampToEdge);
635         }
636
637       // modify the load time to the current time
638       this->LoadTime.Modified();
639
640       // free memory
641       if (resultData != dataPtr)
642         {
643         delete [] resultData;
644         resultData = 0;
645         }
646       }
647     }
648   else
649     {
650     vtkOpenGLRenderWindow* renWin =
651       static_cast<vtkOpenGLRenderWindow*>(ren->GetRenderWindow());
652
653       // has something changed so that we need to rebuild the texture?
654       if (this->GetMTime() > this->LoadTime.GetMTime() ||
655          renWin != this->RenderWindow.GetPointer() ||
656          renWin->GetContextCreationTime() > this->LoadTime)
657         {
658         this->RenderWindow = renWin;
659         this->TextureObject->SetContext(renWin);
660         }
661     }        
662   // activate a free texture unit for this texture
663   this->TextureObject->Activate();
664
665   if (this->PremultipliedAlpha)
666     {
667     // make the blend function correct for textures premultiplied by alpha.
668     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
669     }
670   vtkOpenGLCheckErrorMacro("failed after Load");
671 #endif  
672 }
673
674 void VTKViewer_Texture::Initialize(vtkRenderer * vtkNotUsed(ren))
675 {
676 }
677
678 int VTKViewer_Texture::GetWidth() const
679 {
680   return myWidth;
681 }
682
683 int VTKViewer_Texture::GetHeight() const
684 {
685   return myHeight;
686 }
687
688 void VTKViewer_Texture::SetPosition(int pos)
689 {
690   myPosition = pos;
691 }
692
693 int VTKViewer_Texture::GetPosition() const
694 {
695   return myPosition;
696 }