VTK
vtkOpenGLContextDevice2DPrivate.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkOpenGLContextDevice2DPrivate.h
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
33#ifndef vtkOpenGLContextDevice2DPrivate_h
34#define vtkOpenGLContextDevice2DPrivate_h
35
37
38#include "vtkColor.h"
39#include "vtkTextProperty.h"
40#include "vtkFreeTypeTools.h"
41#include "vtkStdString.h"
42#include "vtkUnicodeString.h"
43
44#include <algorithm>
45#include <list>
46#include <utility>
47
48// .NAME vtkTextureImageCache - store vtkTexture and vtkImageData identified by
49// a unique key.
50// .SECTION Description
51// Creating and initializing a texture can be time consuming,
52// vtkTextureImageCache offers the ability to reuse them as much as possible.
53template <class Key>
55{
56public:
57 struct CacheData
58 {
61 // Dimensions of the text. Used for generating texture coords when the image
62 // dimensions are scaled to a power of two.
65 };
66
68
71 struct CacheElement: public std::pair<Key, CacheData>
72 {
73 // Default constructor
75 : std::pair<Key, CacheData>(Key(), CacheData()){}
76 // Construct a partial CacheElement with no CacheData
77 // This can be used for temporary CacheElement used to search a given
78 // key into the cache list.
79 CacheElement(const Key& key)
80 : std::pair<Key, CacheData>(key, CacheData()){}
81 // Standard constructor of CacheElement
82 CacheElement(const Key& key, const CacheData& cacheData)
83 : std::pair<Key, CacheData>(key, cacheData){}
84 // Operator tuned to be used when searching into the cache list using
85 // std::find()
86 bool operator==(const CacheElement& other)const
87 {
88 // Here we cheat and make the comparison only on the key, this allows
89 // us to use std::find() to search for a given key.
90 return this->first == other.first;
91 }
92 };
94
99 {
100 this->MaxSize = 50;
101 }
102
107 bool IsKeyInCache(const Key& key)const
108 {
109 return std::find(this->Cache.begin(), this->Cache.end(), key) != this->Cache.end();
110 }
111
118 CacheData& GetCacheData(const Key& key);
119
121
126 {
127 typename std::list<CacheElement >::iterator it;
128 for (it = this->Cache.begin(); it != this->Cache.end(); ++it)
129 {
130 it->second.Texture->ReleaseGraphicsResources(window);
131 }
132 }
134
135protected:
137
141 CacheData& AddCacheData(const Key& key, const CacheData& cacheData)
142 {
143 assert(!this->IsKeyInCache(key));
144 if (this->Cache.size() >= this->MaxSize)
145 {
146 this->Cache.pop_back();
147 }
148 this->Cache.push_front(CacheElement(key, cacheData));
149 return this->Cache.begin()->second;
150 }
152
156 std::list<CacheElement > Cache;
158
161 size_t MaxSize;
162};
164
165template<class Key>
168{
169 typename std::list<CacheElement>::iterator it =
170 std::find(this->Cache.begin(), this->Cache.end(), CacheElement(key));
171 if (it != this->Cache.end())
172 {
173 return it->second;
174 }
175 CacheData cacheData;
178 cacheData.Texture->SetInputData(cacheData.ImageData);
179 cacheData.TextWidth = 0;
180 cacheData.TextHeight = 0;
181 return this->AddCacheData(key, cacheData);
182}
183
184// .NAME TextPropertyKey - unique key for a vtkTextProperty and text
185// .SECTION Description
186// Uniquely describe a pair of vtkTextProperty and text.
187template <class StringType>
189{
191
194 static unsigned int GetIdFromTextProperty(vtkTextProperty* textProperty)
195 {
196 size_t id;
198 // Truncation on 64-bit machines! The id is a pointer.
199 return static_cast<unsigned int>(id);
200 }
202
204
207 TextPropertyKey(vtkTextProperty* textProperty, const StringType& text,
208 int dpi)
209 {
210 this->TextPropertyId = GetIdFromTextProperty(textProperty);
211 this->FontSize = textProperty->GetFontSize();
212 double color[3];
213 textProperty->GetColor(color);
214 this->Color.Set(static_cast<unsigned char>(color[0] * 255),
215 static_cast<unsigned char>(color[1] * 255),
216 static_cast<unsigned char>(color[2] * 255),
217 static_cast<unsigned char>(textProperty->GetOpacity() * 255));
218 this->Text = text;
219 this->DPI = dpi;
220 }
222
227 bool operator==(const TextPropertyKey& other)const
228 {
229 return this->TextPropertyId == other.TextPropertyId &&
230 this->FontSize == other.FontSize &&
231 this->Text == other.Text &&
232 this->Color[0] == other.Color[0] &&
233 this->Color[1] == other.Color[1] &&
234 this->Color[2] == other.Color[2] &&
235 this->Color[3] == other.Color[3] &&
236 this->DPI == other.DPI;
237 }
238
239 unsigned short FontSize;
241 // States in the function not to use more than 32 bits - int works fine here.
242 unsigned int TextPropertyId;
243 StringType Text;
244 int DPI;
245};
246
249
251{
252public:
254 {
255 this->Texture = NULL;
258 this->SpriteTexture = NULL;
259 this->SavedLighting = GL_TRUE;
260 this->SavedDepthTest = GL_TRUE;
261 this->SavedAlphaTest = GL_TRUE;
262 this->SavedStencilTest = GL_TRUE;
263 this->SavedBlend = GL_TRUE;
264 this->SavedDrawBuffer = 0;
265 this->SavedClearColor[0] = this->SavedClearColor[1] =
266 this->SavedClearColor[2] =
267 this->SavedClearColor[3] = 0.0f;
268 this->TextCounter = 0;
269 this->GLExtensionsLoaded = false;
270 this->OpenGL15 = false;
271 this->OpenGL20 = false;
272 this->GLSL = false;
273 this->PowerOfTwoTextures = true;
274 }
275
277 {
278 if (this->Texture)
279 {
280 this->Texture->Delete();
281 this->Texture = NULL;
282 }
283 if (this->SpriteTexture)
284 {
285 this->SpriteTexture->Delete();
286 this->SpriteTexture = NULL;
287 }
288 }
289
290 void SaveGLState(bool colorBuffer = false)
291 {
292 this->SavedLighting = glIsEnabled(GL_LIGHTING);
293 this->SavedDepthTest = glIsEnabled(GL_DEPTH_TEST);
294
295 if (colorBuffer)
296 {
297 this->SavedAlphaTest = glIsEnabled(GL_ALPHA_TEST);
298 this->SavedStencilTest = glIsEnabled(GL_STENCIL_TEST);
299 this->SavedBlend = glIsEnabled(GL_BLEND);
300 glGetFloatv(GL_COLOR_CLEAR_VALUE, this->SavedClearColor);
301 glGetIntegerv(GL_DRAW_BUFFER, &this->SavedDrawBuffer);
302 }
303 }
304
305 void RestoreGLState(bool colorBuffer = false)
306 {
307 this->SetGLCapability(GL_LIGHTING, this->SavedLighting);
308 this->SetGLCapability(GL_DEPTH_TEST, this->SavedDepthTest);
309
310 if (colorBuffer)
311 {
312 this->SetGLCapability(GL_ALPHA_TEST, this->SavedAlphaTest);
313 this->SetGLCapability(GL_STENCIL_TEST, this->SavedStencilTest);
314 this->SetGLCapability(GL_BLEND, this->SavedBlend);
315
316 if(this->SavedDrawBuffer != GL_BACK_LEFT)
317 {
318 glDrawBuffer(this->SavedDrawBuffer);
319 }
320
321 int i = 0;
322 bool colorDiffer = false;
323 while(!colorDiffer && i < 4)
324 {
325 colorDiffer=this->SavedClearColor[i++] != 0.0;
326 }
327 if(colorDiffer)
328 {
329 glClearColor(this->SavedClearColor[0],
330 this->SavedClearColor[1],
331 this->SavedClearColor[2],
332 this->SavedClearColor[3]);
333 }
334 }
335 }
336
337 void SetGLCapability(GLenum capability, GLboolean state)
338 {
339 if (state)
340 {
341 glEnable(capability);
342 }
343 else
344 {
345 glDisable(capability);
346 }
347 }
348
349 float* TexCoords(float* f, int n)
350 {
351 float* texCoord = new float[2*n];
352 float minX = f[0]; float minY = f[1];
353 float maxX = f[0]; float maxY = f[1];
354 float* fptr = f;
355 for(int i = 0; i < n; ++i)
356 {
357 minX = fptr[0] < minX ? fptr[0] : minX;
358 maxX = fptr[0] > maxX ? fptr[0] : maxX;
359 minY = fptr[1] < minY ? fptr[1] : minY;
360 maxY = fptr[1] > maxY ? fptr[1] : maxY;
361 fptr+=2;
362 }
363 fptr = f;
365 {
366 double* textureBounds = this->Texture->GetInput()->GetBounds();
367 float rangeX = (textureBounds[1] - textureBounds[0]) ?
368 textureBounds[1] - textureBounds[0] : 1.;
369 float rangeY = (textureBounds[3] - textureBounds[2]) ?
370 textureBounds[3] - textureBounds[2] : 1.;
371 for (int i = 0; i < n; ++i)
372 {
373 texCoord[i*2] = (fptr[0]-minX) / rangeX;
374 texCoord[i*2+1] = (fptr[1]-minY) / rangeY;
375 fptr+=2;
376 }
377 }
378 else // this->TextureProperties & vtkContextDevice2D::Stretch
379 {
380 float rangeX = (maxX - minX)? maxX - minX : 1.f;
381 float rangeY = (maxY - minY)? maxY - minY : 1.f;
382 for (int i = 0; i < n; ++i)
383 {
384 texCoord[i*2] = (fptr[0]-minX)/rangeX;
385 texCoord[i*2+1] = (fptr[1]-minY)/rangeY;
386 fptr+=2;
387 }
388 }
389 return texCoord;
390 }
391
393 {
394 vtkVector2i pow2(1, 1);
395 for (int i = 0; i < 2; ++i)
396 {
397 while (pow2[i] < size[i])
398 {
399 pow2[i] *= 2;
400 }
401 }
402 return pow2;
403 }
404
406 {
407 if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
408 {
409 cout << "Error = not an unsigned char..." << endl;
410 return 0;
411 }
412 int bytesPerPixel = image->GetNumberOfScalarComponents();
413 int size[3];
414 image->GetDimensions(size);
415 vtkVector2i newImg = this->FindPowerOfTwo(vtkVector2i(size[0], size[1]));
416
417 for (int i = 0; i < 2; ++i)
418 {
419 texCoords[i] = size[i] / float(newImg[i]);
420 }
421
422 unsigned char *dataPtr =
423 new unsigned char[newImg[0] * newImg[1] * bytesPerPixel];
424 unsigned char *origPtr =
425 static_cast<unsigned char*>(image->GetScalarPointer());
426
427 for (int i = 0; i < newImg[0]; ++i)
428 {
429 for (int j = 0; j < newImg[1]; ++j)
430 {
431 for (int k = 0; k < bytesPerPixel; ++k)
432 {
433 if (i < size[0] && j < size[1])
434 {
435 dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] =
436 origPtr[i * bytesPerPixel + j * size[0] * bytesPerPixel + k];
437 }
438 else
439 {
440 dataPtr[i * bytesPerPixel + j * newImg[0] * bytesPerPixel + k] =
441 k == 3 ? 0 : 255;
442 }
443 }
444 }
445 }
446
447 GLuint tmpIndex(0);
448 GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
449 GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
450
451 glGenTextures(1, &tmpIndex);
452 glBindTexture(GL_TEXTURE_2D, tmpIndex);
453
454 glTexEnvf(GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_REPLACE);
455 glTexEnvf(GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_REPLACE);
456
457 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
458 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
459 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
460 vtkgl::CLAMP_TO_EDGE );
461 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
462 vtkgl::CLAMP_TO_EDGE );
463
464 glTexImage2D(GL_TEXTURE_2D, 0 , glInternalFormat,
465 newImg[0], newImg[1], 0, glFormat,
466 GL_UNSIGNED_BYTE, static_cast<const GLvoid *>(dataPtr));
467 glAlphaFunc(GL_GREATER, static_cast<GLclampf>(0));
468 glEnable(GL_ALPHA_TEST);
469 glMatrixMode(GL_TEXTURE);
470 glLoadIdentity();
471 glMatrixMode(GL_MODELVIEW);
472 glEnable(GL_TEXTURE_2D);
473 delete [] dataPtr;
474 return tmpIndex;
475 }
476
478 {
479 if (image->GetScalarType() != VTK_UNSIGNED_CHAR)
480 {
481 cout << "Error = not an unsigned char..." << endl;
482 return 0;
483 }
484 int bytesPerPixel = image->GetNumberOfScalarComponents();
485 int size[3];
486 image->GetDimensions(size);
487
488 unsigned char *dataPtr =
489 static_cast<unsigned char*>(image->GetScalarPointer());
490 GLuint tmpIndex(0);
491 GLint glFormat = bytesPerPixel == 3 ? GL_RGB : GL_RGBA;
492 GLint glInternalFormat = bytesPerPixel == 3 ? GL_RGB8 : GL_RGBA8;
493
494 glGenTextures(1, &tmpIndex);
495 glBindTexture(GL_TEXTURE_2D, tmpIndex);
496
497 glTexEnvf(GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_REPLACE);
498 glTexEnvf(GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_REPLACE);
499
500 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
501 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
502 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
503 vtkgl::CLAMP_TO_EDGE );
504 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
505 vtkgl::CLAMP_TO_EDGE );
506
507 glTexImage2D(GL_TEXTURE_2D, 0 , glInternalFormat,
508 size[0], size[1], 0, glFormat,
509 GL_UNSIGNED_BYTE, static_cast<const GLvoid *>(dataPtr));
510 glAlphaFunc(GL_GREATER, static_cast<GLclampf>(0));
511 glEnable(GL_ALPHA_TEST);
512 glMatrixMode(GL_TEXTURE);
513 glLoadIdentity();
514 glMatrixMode(GL_MODELVIEW);
515 glEnable(GL_TEXTURE_2D);
516 return tmpIndex;
517 }
518
520 unsigned int TextureProperties;
522 // Store the previous GL state so that we can restore it when complete
523 GLboolean SavedLighting;
524 GLboolean SavedDepthTest;
525 GLboolean SavedAlphaTest;
527 GLboolean SavedBlend;
529 GLfloat SavedClearColor[4];
530
537 bool GLSL;
539
541
547};
549
550#endif // VTKOPENGLCONTEXTDEVICE2DPRIVATE_H
551// VTK-HeaderTest-Exclude: vtkOpenGLContextDevice2DPrivate.h
TextPropertyKey< vtkUnicodeString > UTF16TextPropertyKey
TextPropertyKey< vtkStdString > UTF8TextPropertyKey
void Set(const T &red, const T &green, const T &blue)
Set the red, green and blue components of the color.
Definition: vtkColor.h:129
double * GetBounds()
Return a pointer to the geometry bounding box in the form (xmin,xmax, ymin,ymax, zmin,...
void MapTextPropertyToId(vtkTextProperty *tprop, size_t *tprop_cache_id)
Given a text property 'tprop', get its unique ID in our cache framework.
static vtkFreeTypeTools * GetInstance()
Return the singleton instance with no reference counting.
void SetInputData(vtkDataObject *)
Assign a data object as input.
topologically and geometrically regular array of data
Definition: vtkImageData.h:46
virtual void Delete()
Delete a VTK object.
vtkTextureImageCache< UTF16TextPropertyKey > TextTextureCache
Cache for text images.
vtkVector2i FindPowerOfTwo(const vtkVector2i &size)
vtkTextureImageCache< UTF8TextPropertyKey > MathTextTextureCache
GLuint TextureFromImage(vtkImageData *image, vtkVector2f &texCoords)
void SetGLCapability(GLenum capability, GLboolean state)
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
represent text properties.
virtual double GetOpacity()
virtual int GetFontSize()
virtual double * GetColor()
bool IsKeyInCache(const Key &key) const
Search the cache list to see if a given key already exists.
std::list< CacheElement > Cache
List of a pair of key and cache data.
CacheData & AddCacheData(const Key &key, const CacheData &cacheData)
Add a new cache entry into the cache list.
void ReleaseGraphicsResources(vtkWindow *window)
Release all the OpenGL Pixel Buffer Object(PBO) associated with the textures of the cache list.
vtkTextureImageCache()
Construct a texture image cache with a maximum number of texture of 50.
size_t MaxSize
Maximum size the cache list can be.
CacheData & GetCacheData(const Key &key)
Return the cache associated to a key.
handles properties associated with a texture map
Definition: vtkTexture.h:71
vtkImageData * GetInput()
Get the input as a vtkImageData object.
Some derived classes for the different vectors commonly used.
Definition: vtkVector.h:328
window superclass for vtkRenderWindow
Definition: vtkWindow.h:35
@ key
Definition: vtkX3D.h:257
@ color
Definition: vtkX3D.h:221
@ image
Definition: vtkX3D.h:374
@ size
Definition: vtkX3D.h:253
TextPropertyKey(vtkTextProperty *textProperty, const StringType &text, int dpi)
Creates a TextPropertyKey.
static unsigned int GetIdFromTextProperty(vtkTextProperty *textProperty)
Transform a text property into an unsigned long.
bool operator==(const TextPropertyKey &other) const
Compares two TextPropertyKeys with each other.
vtkSmartPointer< vtkImageData > ImageData
CacheElement associates a unique key to some cache.
CacheElement(const Key &key, const CacheData &cacheData)
bool operator==(const CacheElement &other) const
#define VTK_UNSIGNED_CHAR
Definition: vtkType.h:51