1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkOpenGLPainterDeviceAdapter.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 /*
16 * Copyright 2004 Sandia Corporation.
17 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
18 * license for use of this work by or on behalf of the
19 * U.S. Government. Redistribution and use in source and binary forms, with
20 * or without modification, are permitted provided that this Notice and any
21 * statement of authorship are reproduced on all copies.
22 */
23
24 #include "vtkOpenGLPainterDeviceAdapter.h"
25
26 #include "vtkDataArray.h"
27 #include "vtkDataSetAttributes.h"
28 #include "vtkObjectFactory.h"
29 #include "vtkOpenGLGL2PSHelper.h"
30 #include "vtkOpenGLRenderWindow.h"
31 #ifndef VTK_LEGACY_REMOVE
32 #include "vtkOpenGLExtensionManager.h"
33 #endif
34 #include "vtkRenderer.h"
35 #include "vtkgl.h"
36
37 #include <algorithm>
38
39 #include "vtkOpenGL.h"
40 #include "vtkOpenGLError.h"
41
42 vtkStandardNewMacro(vtkOpenGLPainterDeviceAdapter);
43
44 //-----------------------------------------------------------------------------
vtkOpenGLPainterDeviceAdapter()45 vtkOpenGLPainterDeviceAdapter::vtkOpenGLPainterDeviceAdapter()
46 {
47 this->PointSize = 1.0;
48 this->RangeNear = 0.0;
49 this->RangeFar = 1.0;
50 this->MaxStencil = 0;
51 this->Initialized = false;
52 }
53
54 //-----------------------------------------------------------------------------
~vtkOpenGLPainterDeviceAdapter()55 vtkOpenGLPainterDeviceAdapter::~vtkOpenGLPainterDeviceAdapter()
56 {
57 }
58
59 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)60 void vtkOpenGLPainterDeviceAdapter::PrintSelf(ostream &os, vtkIndent indent)
61 {
62 this->Superclass::PrintSelf(os, indent);
63 }
64
65 //-----------------------------------------------------------------------------
66
67 // This array is a map from VTK primitive identifiers (VTK_VERTEX, VTK_LINE,
68 // etc.) to OpenGL polygon primitive identifiers (GL_POINTS, GL_LINES, etc.)
69 // Note that some VTK polygon types (e.g. VTK_EMPTY_CELL and VTK_PIXEL) have no
70 // analogue in OpenGL. Using them will undoubtedly result in an OpenGL error.
71 static const GLenum VTK2OpenGLPrimitive[] = {
72 static_cast<GLenum>(0xFFFF), // 0 - VTK_EMPTY_CELL
73 GL_POINTS, // 1 - VTK_VERTEX
74 GL_POINTS, // 2 - VTK_POLY_VERTEX
75 GL_LINES, // 3 - VTK_LINE
76 GL_LINE_STRIP, // 4 - VTK_POLY_LINE
77 GL_TRIANGLES, // 5 - VTK_TRIANGLE
78 GL_TRIANGLE_STRIP, // 6 - VTK_TRIANGLE_STRIP
79 GL_POLYGON, // 7 - VTK_POLYGON
80 static_cast<GLenum>(0xFFFF), // 8 - VTK_PIXEL
81 GL_QUADS, // 9 - VTK_QUAD
82 GL_LINE_LOOP // 10 - VTK_TETRA
83 };
84
VTK2OpenGLType(int type)85 static inline GLenum VTK2OpenGLType(int type)
86 {
87 switch (type)
88 {
89 #if VTK_SIZEOF_CHAR == 1
90 case VTK_CHAR: return GL_BYTE;
91 case VTK_UNSIGNED_CHAR: return GL_UNSIGNED_BYTE;
92 #elif VTK_SIZE_OF_CHAR == 2
93 case VTK_CHAR: return GL_SHORT;
94 case VTK_UNSIGNED CHAR: return GL_UNSIGNED_SHORT;
95 #endif
96
97 #if VTK_SIZEOF_SHORT == 1
98 case VTK_SHORT: return GL_BYTE;
99 case VTK_UNSIGNED_SHORT: return GL_UNSIGNED_BYTE;
100 #elif VTK_SIZEOF_SHORT == 2
101 case VTK_SHORT: return GL_SHORT;
102 case VTK_UNSIGNED_SHORT: return GL_UNSIGNED_SHORT;
103 #elif VTK_SIZEOF_SHORT == 4
104 case VTK_SHORT: return GL_INT;
105 case VTK_UNSIGNED_SHORT: return GL_UNSIGNED_INT;
106 #endif
107
108 #if VTK_SIZEOF_INT == 2
109 case VTK_INT: return GL_SHORT;
110 case VTK_UNSIGNED_INT: return GL_UNSIGNED_SHORT;
111 #elif VTK_SIZEOF_INT == 4
112 case VTK_INT: return GL_INT;
113 case VTK_UNSIGNED_INT: return GL_UNSIGNED_INT;
114 #endif
115
116 #if VTK_SIZEOF_LONG == 4
117 case VTK_LONG: return GL_INT;
118 case VTK_UNSIGNED_LONG: return GL_UNSIGNED_INT;
119 #endif
120
121 #if VTK_SIZEOF_ID_TYPE == 4
122 case VTK_ID_TYPE: return GL_INT;
123 #endif
124
125 #if VTK_SIZEOF_FLOAT == 4
126 case VTK_FLOAT: return GL_FLOAT;
127 #elif VTK_SIZEOF_FLOAT == 8
128 case VTK_FLOAT: return GL_DOUBLE;
129 #endif
130
131 #if VTK_SIZEOF_DOUBLE == 4
132 case VTK_DOUBLE: return GL_FLOAT;
133 #elif VTK_SIZEOF_DOUBLE == 8
134 case VTK_DOUBLE: return GL_DOUBLE;
135 #endif
136
137 default: return GL_FALSE;
138 }
139 }
140
VTK2SignedOpenGLType(int type)141 static inline GLenum VTK2SignedOpenGLType(int type)
142 {
143 switch (type)
144 {
145 #if VTK_SIZEOF_CHAR == 1
146 case VTK_CHAR: return GL_BYTE;
147 case VTK_UNSIGNED_CHAR: return GL_BYTE;
148 #elif VTK_SIZE_OF_CHAR == 2
149 case VTK_CHAR: return GL_SHORT;
150 case VTK_UNSIGNED CHAR: return GL_SHORT;
151 #endif
152
153 #if VTK_SIZEOF_SHORT == 1
154 case VTK_SHORT: return GL_BYTE;
155 case VTK_UNSIGNED_SHORT: return GL_BYTE;
156 #elif VTK_SIZEOF_SHORT == 2
157 case VTK_SHORT: return GL_SHORT;
158 case VTK_UNSIGNED_SHORT: return GL_SHORT;
159 #elif VTK_SIZEOF_SHORT == 4
160 case VTK_SHORT: return GL_INT;
161 case VTK_UNSIGNED_SHORT: return GL_INT;
162 #endif
163
164 #if VTK_SIZEOF_INT == 2
165 case VTK_INT: return GL_SHORT;
166 case VTK_UNSIGNED_INT: return GL_SHORT;
167 #elif VTK_SIZEOF_INT == 4
168 case VTK_INT: return GL_INT;
169 case VTK_UNSIGNED_INT: return GL_INT;
170 #endif
171
172 #if VTK_SIZEOF_ID_TYPE == 4
173 case VTK_ID_TYPE: return GL_INT;
174 #endif
175
176 #if VTK_SIZEOF_LONG == 4
177 case VTK_LONG: return GL_INT;
178 case VTK_UNSIGNED_LONG: return GL_INT;
179 #endif
180
181 #if VTK_SIZEOF_FLOAT == 4
182 case VTK_FLOAT: return GL_FLOAT;
183 #elif VTK_SIZEOF_FLOAT == 8
184 case VTK_FLOAT: return GL_DOUBLE;
185 #endif
186
187 #if VTK_SIZEOF_DOUBLE == 4
188 case VTK_DOUBLE: return GL_FLOAT;
189 #elif VTK_SIZEOF_DOUBLE == 8
190 case VTK_DOUBLE: return GL_DOUBLE;
191 #endif
192
193 default: return GL_FALSE;
194 }
195 }
196
VTK2UnsignedOpenGLType(int type)197 static inline GLenum VTK2UnsignedOpenGLType(int type)
198 {
199 switch (type)
200 {
201 #if VTK_SIZEOF_CHAR == 1
202 case VTK_CHAR: return GL_UNSIGNED_BYTE;
203 case VTK_UNSIGNED_CHAR: return GL_UNSIGNED_BYTE;
204 #elif VTK_SIZE_OF_CHAR == 2
205 case VTK_CHAR: return GL_UNSIGNED_SHORT;
206 case VTK_UNSIGNED CHAR: return GL_UNSIGNED_SHORT;
207 #endif
208
209 #if VTK_SIZEOF_SHORT == 1
210 case VTK_SHORT: return GL_UNSIGNED_BYTE;
211 case VTK_UNSIGNED_SHORT: return GL_UNSIGNED_BYTE;
212 #elif VTK_SIZEOF_SHORT == 2
213 case VTK_SHORT: return GL_UNSIGNED_SHORT;
214 case VTK_UNSIGNED_SHORT: return GL_UNSIGNED_SHORT;
215 #elif VTK_SIZEOF_SHORT == 4
216 case VTK_SHORT: return GL_UNSIGNED_INT;
217 case VTK_UNSIGNED_SHORT: return GL_UNSIGNED_INT;
218 #endif
219
220 #if VTK_SIZEOF_INT == 2
221 case VTK_INT: return GL_UNSIGNED_SHORT;
222 case VTK_UNSIGNED_INT: return GL_UNSIGNED_SHORT;
223 #elif VTK_SIZEOF_INT == 4
224 case VTK_INT: return GL_UNSIGNED_INT;
225 case VTK_UNSIGNED_INT: return GL_UNSIGNED_INT;
226 #endif
227
228 #if VTK_SIZEOF_ID_TYPE == 4
229 case VTK_ID_TYPE: return GL_UNSIGNED_INT;
230 #endif
231
232 #if VTK_SIZEOF_LONG == 4
233 case VTK_LONG: return GL_UNSIGNED_INT;
234 case VTK_UNSIGNED_LONG: return GL_UNSIGNED_INT;
235 #endif
236
237 default: return GL_FALSE;
238 }
239 }
240
241
242 //-----------------------------------------------------------------------------
BeginPrimitive(int mode)243 void vtkOpenGLPainterDeviceAdapter::BeginPrimitive(int mode)
244 {
245 glBegin(VTK2OpenGLPrimitive[mode]);
246 }
247
248 //-----------------------------------------------------------------------------
EndPrimitive()249 void vtkOpenGLPainterDeviceAdapter::EndPrimitive()
250 {
251 glEnd();
252 }
253
254 //-----------------------------------------------------------------------------
IsAttributesSupported(int attribute)255 int vtkOpenGLPainterDeviceAdapter::IsAttributesSupported(int attribute)
256 {
257 switch(attribute)
258 {
259 case vtkDataSetAttributes::NUM_ATTRIBUTES:
260 case vtkDataSetAttributes::NORMALS:
261 case vtkDataSetAttributes::SCALARS:
262 case vtkDataSetAttributes::TCOORDS:
263 case vtkDataSetAttributes::EDGEFLAG:
264 return 1;
265 }
266 return 0;
267 }
268
269 //-----------------------------------------------------------------------------
SendAttribute(int index,int numcomp,int type,const void * attribute,vtkIdType offset)270 void vtkOpenGLPainterDeviceAdapter::SendAttribute(int index, int numcomp,
271 int type, const void *attribute, vtkIdType offset/*=0*/)
272 {
273 switch (index)
274 {
275 case vtkDataSetAttributes::NUM_ATTRIBUTES: // Vertex
276 if ((numcomp < 2) || (numcomp > 4))
277 {
278 vtkErrorMacro("Bad number of components.");
279 return;
280 }
281 switch (VTK2SignedOpenGLType(type))
282 {
283 case GL_SHORT:
284 switch (numcomp)
285 {
286 case 2:
287 glVertex2sv(static_cast<const GLshort *>(attribute) + offset);
288 break;
289 case 3:
290 glVertex3sv(static_cast<const GLshort *>(attribute) + offset);
291 break;
292 case 4:
293 glVertex4sv(static_cast<const GLshort *>(attribute) + offset);
294 break;
295 }
296 break;
297 case GL_INT:
298 switch (numcomp)
299 {
300 case 2:
301 glVertex2iv(static_cast<const GLint *>(attribute) + offset);
302 break;
303 case 3:
304 glVertex3iv(static_cast<const GLint *>(attribute) + offset);
305 break;
306 case 4:
307 glVertex4iv(static_cast<const GLint *>(attribute) + offset);
308 break;
309 }
310 break;
311 case GL_FLOAT:
312 switch (numcomp)
313 {
314 case 2:
315 glVertex2fv(static_cast<const GLfloat *>(attribute) + offset);
316 break;
317 case 3:
318 glVertex3fv(static_cast<const GLfloat *>(attribute) + offset);
319 break;
320 case 4:
321 glVertex4fv(static_cast<const GLfloat *>(attribute) + offset);
322 break;
323 }
324 break;
325 case GL_DOUBLE:
326 switch (numcomp)
327 {
328 case 2:
329 glVertex2dv(static_cast<const GLdouble *>(attribute) + offset);
330 break;
331 case 3:
332 glVertex3dv(static_cast<const GLdouble *>(attribute) + offset);
333 break;
334 case 4:
335 glVertex4dv(static_cast<const GLdouble *>(attribute) + offset);
336 break;
337 }
338 break;
339 default:
340 vtkErrorMacro("Unsupported type for vertices: " << type);
341 return;
342 }
343 break;
344 case vtkDataSetAttributes::NORMALS: // Normal
345 if (numcomp != 3)
346 {
347 vtkErrorMacro("Bad number of components.");
348 return;
349 }
350 switch (VTK2SignedOpenGLType(type))
351 {
352 case GL_BYTE:
353 glNormal3bv(static_cast<const GLbyte *>(attribute) + offset);
354 break;
355 case GL_SHORT:
356 glNormal3sv(static_cast<const GLshort *>(attribute) + offset);
357 break;
358 case GL_INT:
359 glNormal3iv(static_cast<const GLint *>(attribute) + offset);
360 break;
361 case GL_FLOAT:
362 glNormal3fv(static_cast<const GLfloat *>(attribute) + offset);
363 break;
364 case GL_DOUBLE:
365 glNormal3dv(static_cast<const GLdouble *>(attribute) + offset);
366 break;
367 default:
368 vtkErrorMacro("Unsupported type for normals: " << type);
369 return;
370 }
371 break;
372 case vtkDataSetAttributes::SCALARS: // Color
373 if ((numcomp != 3) && (numcomp != 4))
374 {
375 vtkErrorMacro("Bad number of components.");
376 return;
377 }
378 switch (VTK2OpenGLType(type))
379 {
380 case GL_BYTE:
381 switch (numcomp)
382 {
383 case 3: glColor3bv(static_cast<const GLbyte *>(attribute) + offset);
384 break;
385 case 4: glColor4bv(static_cast<const GLbyte *>(attribute) + offset);
386 break;
387 }
388 break;
389 case GL_UNSIGNED_BYTE:
390 switch (numcomp)
391 {
392 case 3: glColor3ubv(static_cast<const GLubyte *>(attribute) + offset);
393 break;
394 case 4: glColor4ubv(static_cast<const GLubyte *>(attribute) + offset);
395 break;
396 }
397 break;
398 case GL_SHORT:
399 switch (numcomp)
400 {
401 case 3: glColor3sv(static_cast<const GLshort *>(attribute) + offset);
402 break;
403 case 4: glColor4sv(static_cast<const GLshort *>(attribute) + offset);
404 break;
405 }
406 break;
407 case GL_UNSIGNED_SHORT:
408 switch (numcomp)
409 {
410 case 3: glColor3usv(static_cast<const GLushort *>(attribute) + offset);
411 break;
412 case 4: glColor4usv(static_cast<const GLushort *>(attribute) + offset);
413 break;
414 }
415 break;
416 case GL_INT:
417 switch (numcomp)
418 {
419 case 3: glColor3iv(static_cast<const GLint *>(attribute) + offset);
420 break;
421 case 4: glColor4iv(static_cast<const GLint *>(attribute) + offset);
422 break;
423 }
424 break;
425 case GL_UNSIGNED_INT:
426 switch (numcomp)
427 {
428 case 3: glColor3uiv(static_cast<const GLuint *>(attribute) + offset);
429 break;
430 case 4: glColor4uiv(static_cast<const GLuint *>(attribute) + offset);
431 break;
432 }
433 break;
434 case GL_FLOAT:
435 switch (numcomp)
436 {
437 case 3: glColor3fv(static_cast<const GLfloat *>(attribute) + offset);
438 break;
439 case 4: glColor4fv(static_cast<const GLfloat *>(attribute) + offset);
440 break;
441 }
442 break;
443 case GL_DOUBLE:
444 switch (numcomp)
445 {
446 case 3: glColor3dv(static_cast<const GLdouble *>(attribute) + offset);
447 break;
448 case 4: glColor4dv(static_cast<const GLdouble *>(attribute) + offset);
449 break;
450 }
451 break;
452 default:
453 vtkErrorMacro("Unsupported type for colors: " << type);
454 return;
455 }
456 break;
457
458 case vtkDataSetAttributes::TCOORDS: // Texture Coordinate
459 if ((numcomp < 1) || (numcomp > 4))
460 {
461 vtkErrorMacro("Bad number of components.");
462 return;
463 }
464 switch (VTK2SignedOpenGLType(type))
465 {
466 case GL_SHORT:
467 switch (numcomp)
468 {
469 case 1:
470 glTexCoord1sv(static_cast<const GLshort *>(attribute) + offset);
471 break;
472 case 2:
473 glTexCoord2sv(static_cast<const GLshort *>(attribute) + offset);
474 break;
475 case 3:
476 glTexCoord3sv(static_cast<const GLshort *>(attribute) + offset);
477 break;
478 case 4:
479 glTexCoord4sv(static_cast<const GLshort *>(attribute) + offset);
480 break;
481 }
482 break;
483 case GL_INT:
484 switch (numcomp)
485 {
486 case 1:
487 glTexCoord1iv(static_cast<const GLint *>(attribute) + offset);
488 break;
489 case 2:
490 glTexCoord2iv(static_cast<const GLint *>(attribute) + offset);
491 break;
492 case 3:
493 glTexCoord3iv(static_cast<const GLint *>(attribute) + offset);
494 break;
495 case 4:
496 glTexCoord4iv(static_cast<const GLint *>(attribute) + offset);
497 break;
498 }
499 break;
500 case GL_FLOAT:
501 switch (numcomp)
502 {
503 case 1:
504 glTexCoord1fv(static_cast<const GLfloat *>(attribute) + offset);
505 break;
506 case 2:
507 glTexCoord2fv(static_cast<const GLfloat *>(attribute) + offset);
508 break;
509 case 3:
510 glTexCoord3fv(static_cast<const GLfloat *>(attribute) + offset);
511 break;
512 case 4:
513 glTexCoord4fv(static_cast<const GLfloat *>(attribute) + offset);
514 break;
515 }
516 break;
517 case GL_DOUBLE:
518 switch (numcomp)
519 {
520 case 1:
521 glTexCoord1dv(static_cast<const GLdouble *>(attribute) + offset);
522 break;
523 case 2:
524 glTexCoord2dv(static_cast<const GLdouble *>(attribute) + offset);
525 break;
526 case 3:
527 glTexCoord3dv(static_cast<const GLdouble *>(attribute) + offset);
528 break;
529 case 4:
530 glTexCoord4dv(static_cast<const GLdouble *>(attribute) + offset);
531 break;
532 }
533 break;
534 default:
535 vtkErrorMacro("Unsupported type for texture coordinates: " << type);
536 return;
537 }
538 break;
539 case vtkDataSetAttributes::EDGEFLAG: // Edge Flag
540 if (numcomp != 1)
541 {
542 vtkErrorMacro("Bad number of components.");
543 return;
544 }
545 switch (type)
546 {
547 vtkTemplateMacro(glEdgeFlag(static_cast<GLboolean>(
548 reinterpret_cast<const VTK_TT*>(attribute)[offset])));
549 }
550 break;
551 default:
552 vtkErrorMacro("Unsupported attribute index: " << index);
553 return;
554 };
555 }
556
557 //-----------------------------------------------------------------------------
SendMultiTextureCoords(int numcomp,int type,const void * attribute,int idx,vtkIdType offset)558 void vtkOpenGLPainterDeviceAdapter::SendMultiTextureCoords(int numcomp,
559 int type, const void *attribute, int idx, vtkIdType offset)
560 {
561 if(! vtkgl::MultiTexCoord2d)
562 {
563 vtkErrorMacro("MultiTexturing not supported.");
564 return;
565 }
566
567 if ((numcomp < 1) || (numcomp > 4))
568 {
569 vtkErrorMacro("Bad number of components.");
570 return;
571 }
572
573 int textureIndex = vtkgl::TEXTURE0 + idx;
574 switch (VTK2SignedOpenGLType(type))
575 {
576 case GL_SHORT:
577 switch (numcomp)
578 {
579 case 1:
580 vtkgl::MultiTexCoord1sv(textureIndex, static_cast<const GLshort *>(attribute) + offset);
581 break;
582 case 2:
583 vtkgl::MultiTexCoord2sv(textureIndex, static_cast<const GLshort *>(attribute) + offset);
584 break;
585 case 3:
586 vtkgl::MultiTexCoord3sv(textureIndex, static_cast<const GLshort *>(attribute) + offset);
587 break;
588 case 4:
589 vtkgl::MultiTexCoord4sv(textureIndex, static_cast<const GLshort *>(attribute) + offset);
590 break;
591 }
592 break;
593 case GL_INT:
594 switch (numcomp)
595 {
596 case 1:
597 vtkgl::MultiTexCoord1iv(textureIndex, static_cast<const GLint *>(attribute) + offset);
598 break;
599 case 2:
600 vtkgl::MultiTexCoord2iv(textureIndex, static_cast<const GLint *>(attribute) + offset);
601 break;
602 case 3:
603 vtkgl::MultiTexCoord3iv(textureIndex, static_cast<const GLint *>(attribute) + offset);
604 break;
605 case 4:
606 vtkgl::MultiTexCoord4iv(textureIndex, static_cast<const GLint *>(attribute) + offset);
607 break;
608 }
609 break;
610 case GL_FLOAT:
611 switch (numcomp)
612 {
613 case 1:
614 vtkgl::MultiTexCoord1fv(textureIndex, static_cast<const GLfloat *>(attribute) + offset);
615 break;
616 case 2:
617 vtkgl::MultiTexCoord2fv(textureIndex, static_cast<const GLfloat *>(attribute) + offset);
618 break;
619 case 3:
620 vtkgl::MultiTexCoord3fv(textureIndex, static_cast<const GLfloat *>(attribute) + offset);
621 break;
622 case 4:
623 vtkgl::MultiTexCoord4fv(textureIndex, static_cast<const GLfloat *>(attribute) + offset);
624 break;
625 }
626 break;
627 case GL_DOUBLE:
628 switch (numcomp)
629 {
630 case 1:
631 vtkgl::MultiTexCoord1dv(textureIndex, static_cast<const GLdouble *>(attribute) + offset);
632 break;
633 case 2:
634 vtkgl::MultiTexCoord2dv(textureIndex, static_cast<const GLdouble *>(attribute) + offset);
635 break;
636 case 3:
637 vtkgl::MultiTexCoord3dv(textureIndex, static_cast<const GLdouble *>(attribute) + offset);
638 break;
639 case 4:
640 vtkgl::MultiTexCoord4dv(textureIndex, static_cast<const GLdouble *>(attribute) + offset);
641 break;
642 }
643 break;
644 default:
645 vtkErrorMacro("Unsupported type for texture coordinates: " << type);
646 return;
647 }
648
649 }
650
651 //-----------------------------------------------------------------------------
652
SetAttributePointer(int index,int numcomponents,int type,int stride,const void * pointer)653 void vtkOpenGLPainterDeviceAdapter::SetAttributePointer(int index,
654 int numcomponents,
655 int type, int stride,
656 const void *pointer)
657 {
658 GLenum gltype;
659
660 switch (index)
661 {
662 case vtkDataSetAttributes::NUM_ATTRIBUTES: // Vertex
663 gltype = VTK2SignedOpenGLType(type);
664 switch (gltype)
665 {
666 case GL_SHORT:
667 case GL_INT:
668 case GL_FLOAT:
669 case GL_DOUBLE:
670 break;
671 default:
672 vtkErrorMacro("Unsupported type for vertices: " << type);
673 return;
674 }
675 glVertexPointer(numcomponents, gltype, stride, pointer);
676 break;
677 case vtkDataSetAttributes::NORMALS: // Normal
678 gltype = VTK2SignedOpenGLType(type);
679 switch (gltype)
680 {
681 case GL_BYTE:
682 case GL_SHORT:
683 case GL_INT:
684 case GL_FLOAT:
685 case GL_DOUBLE:
686 break;
687 default:
688 vtkErrorMacro("Unsupported type for normals: " << type);
689 return;
690 }
691 if (numcomponents != 3)
692 {
693 vtkErrorMacro("Unsupported number of components for normals.");
694 return;
695 }
696 glNormalPointer(gltype, stride, pointer);
697 break;
698 case vtkDataSetAttributes::SCALARS: // Color
699 gltype = VTK2OpenGLType(type);
700 switch (gltype)
701 {
702 case GL_BYTE:
703 case GL_UNSIGNED_BYTE:
704 case GL_SHORT:
705 case GL_UNSIGNED_SHORT:
706 case GL_INT:
707 case GL_UNSIGNED_INT:
708 case GL_FLOAT:
709 case GL_DOUBLE:
710 break;
711 default:
712 vtkErrorMacro("Unsupported type for colors: " << type);
713 return;
714 }
715 glColorPointer(numcomponents, gltype, stride, pointer);
716 break;
717 case vtkDataSetAttributes::TCOORDS: // Texture Coordinate
718 gltype = VTK2SignedOpenGLType(type);
719 switch (gltype)
720 {
721 case GL_SHORT:
722 case GL_INT:
723 case GL_FLOAT:
724 case GL_DOUBLE:
725 break;
726 default:
727 vtkErrorMacro("Unsupported type for texture coordinates: " << type);
728 return;
729 }
730 glTexCoordPointer(numcomponents, gltype, stride, pointer);
731 break;
732 case vtkDataSetAttributes::EDGEFLAG: // Edge flag
733 if (numcomponents != 1)
734 {
735 vtkErrorMacro("Edge flag must have one component.");
736 return;
737 }
738 // Flag must be conformant to GLboolean
739 if ((type == VTK_FLOAT) || (type == GL_DOUBLE))
740 {
741 vtkErrorMacro("Unsupported type for edge flag: " << type);
742 return;
743 }
744 // Thus is an unfriendly way to force the array to be conformant to
745 // a GLboolean array. At the very least there should be some indication
746 // in VTK outside of OpenGL to determine which VTK type to use.
747 switch (type)
748 {
749 vtkTemplateMacro(if (sizeof(VTK_TT) != sizeof(GLboolean))
750 {
751 vtkErrorMacro(<< "Unsupported tyep for edge flag: "
752 << type);
753 return;
754 }
755 );
756 }
757 glEdgeFlagPointer(stride, pointer);
758 break;
759 default:
760 vtkErrorMacro("Unsupported attribute index: " << index);
761 return;
762 };
763 }
764
765 //-----------------------------------------------------------------------------
766
EnableAttributeArray(int index)767 void vtkOpenGLPainterDeviceAdapter::EnableAttributeArray(int index)
768 {
769 switch (index)
770 {
771 case vtkDataSetAttributes::NUM_ATTRIBUTES:
772 glEnableClientState(GL_VERTEX_ARRAY); break;
773 case vtkDataSetAttributes::NORMALS:
774 glEnableClientState(GL_NORMAL_ARRAY); break;
775 case vtkDataSetAttributes::SCALARS:
776 glEnableClientState(GL_COLOR_ARRAY); break;
777 case vtkDataSetAttributes::TCOORDS:
778 glEnableClientState(GL_TEXTURE_COORD_ARRAY); break;
779 case vtkDataSetAttributes::EDGEFLAG:
780 glEnableClientState(GL_EDGE_FLAG_ARRAY); break;
781 default:
782 vtkErrorMacro("Unsupported attribute index: " << index);
783 return;
784 };
785 }
786
DisableAttributeArray(int index)787 void vtkOpenGLPainterDeviceAdapter::DisableAttributeArray(int index)
788 {
789 switch (index)
790 {
791 case vtkDataSetAttributes::NUM_ATTRIBUTES:
792 glDisableClientState(GL_VERTEX_ARRAY); break;
793 case vtkDataSetAttributes::NORMALS:
794 glDisableClientState(GL_NORMAL_ARRAY); break;
795 case vtkDataSetAttributes::SCALARS:
796 glDisableClientState(GL_COLOR_ARRAY); break;
797 case vtkDataSetAttributes::TCOORDS:
798 glDisableClientState(GL_TEXTURE_COORD_ARRAY); break;
799 case vtkDataSetAttributes::EDGEFLAG:
800 glDisableClientState(GL_EDGE_FLAG_ARRAY); break;
801 default:
802 vtkErrorMacro("Unsupported attribute index: " << index);
803 return;
804 };
805 }
806
807 //-----------------------------------------------------------------------------
808
DrawArrays(int mode,vtkIdType first,vtkIdType count)809 void vtkOpenGLPainterDeviceAdapter::DrawArrays(int mode, vtkIdType first,
810 vtkIdType count)
811 {
812 glDrawArrays(VTK2OpenGLPrimitive[mode],static_cast<GLint>(first),
813 static_cast<GLsizei>(count));
814 }
815
DrawElements(int mode,vtkIdType count,int type,void * indices)816 void vtkOpenGLPainterDeviceAdapter::DrawElements(int mode, vtkIdType count,
817 int type, void *indices)
818 {
819 GLenum gltype = VTK2UnsignedOpenGLType(type);
820 switch (gltype)
821 {
822 case GL_UNSIGNED_BYTE:
823 case GL_UNSIGNED_SHORT:
824 case GL_UNSIGNED_INT:
825 break;
826 default:
827 if (type == VTK_ID_TYPE)
828 {
829 // This seems really inefficient for handling vtkIdType when they
830 // are 64 bit, but OpenGL does not handle 64 bit indices. What
831 // else can I do?
832 vtkIdType *oldarray = static_cast<vtkIdType *>(indices);
833 GLuint *newarray = new GLuint[count];
834 std::copy(oldarray, oldarray + count, newarray);
835 glDrawElements(VTK2OpenGLPrimitive[mode], static_cast<GLsizei>(count),
836 GL_UNSIGNED_INT, newarray);
837 delete[] newarray;
838 return;
839 }
840 else
841 {
842 vtkErrorMacro("Invalid type for indices.");
843 return;
844 }
845 }
846 glDrawElements(VTK2OpenGLPrimitive[mode],static_cast<GLsizei>(count), gltype,
847 indices);
848 }
849
850 //-----------------------------------------------------------------------------
Compatible(vtkRenderer * renderer)851 int vtkOpenGLPainterDeviceAdapter::Compatible(vtkRenderer *renderer)
852 {
853 vtkOpenGLRenderWindow *context
854 = vtkOpenGLRenderWindow::SafeDownCast(renderer->GetRenderWindow());
855 if (!context)
856 {
857 return false;
858 }
859 #ifndef VTK_LEGACY_REMOVE
860 vtkOpenGLExtensionManager *manager = context->GetExtensionManager();
861 if (!manager->ExtensionSupported("GL_ARB_multisample"))
862 {
863 return false;
864 }
865 #endif
866 return true;
867 }
868
869 #ifndef VTK_LEGACY_REMOVE
870 //-----------------------------------------------------------------------------
MakeLighting(int mode)871 void vtkOpenGLPainterDeviceAdapter::MakeLighting(int mode)
872 {
873 VTK_LEGACY_BODY(vtkOpenGLPainterDeviceAdapter::MakeLighting, "VTK 6.1");
874 if (mode)
875 {
876 glEnable(GL_LIGHTING);
877 }
878 else
879 {
880 glDisable(GL_LIGHTING);
881 }
882 }
883
884 //-----------------------------------------------------------------------------
QueryLighting()885 int vtkOpenGLPainterDeviceAdapter::QueryLighting()
886 {
887 VTK_LEGACY_BODY(vtkOpenGLPainterDeviceAdapter::QueryLighting, "VTK 6.1");
888 if (glIsEnabled(GL_LIGHTING))
889 {
890 return 1;
891 }
892 else
893 {
894 return 0;
895 }
896 }
897
898 //-----------------------------------------------------------------------------
MakeMultisampling(int mode)899 void vtkOpenGLPainterDeviceAdapter::MakeMultisampling(int mode)
900 {
901 VTK_LEGACY_BODY(vtkOpenGLPainterDeviceAdapter::MakeMultisampling, "VTK 6.1");
902 if (mode)
903 {
904 glEnable(vtkgl::MULTISAMPLE);
905 }
906 else
907 {
908 glDisable(vtkgl::MULTISAMPLE);
909 }
910 }
911
912 //-----------------------------------------------------------------------------
QueryMultisampling()913 int vtkOpenGLPainterDeviceAdapter::QueryMultisampling()
914 {
915 VTK_LEGACY_BODY(vtkOpenGLPainterDeviceAdapter::QueryMultisampling, "VTK 6.1");
916 if (glIsEnabled(vtkgl::MULTISAMPLE))
917 {
918 return 1;
919 }
920 else
921 {
922 return 0;
923 }
924 }
925
926 //-----------------------------------------------------------------------------
MakeBlending(int mode)927 void vtkOpenGLPainterDeviceAdapter::MakeBlending(int mode)
928 {
929 VTK_LEGACY_BODY(vtkOpenGLPainterDeviceAdapter::MakeBlending, "VTK 6.1");
930 if (mode)
931 {
932 glEnable(GL_BLEND);
933 }
934 else
935 {
936 glDisable(GL_BLEND);
937 }
938 }
939
940 //-----------------------------------------------------------------------------
QueryBlending()941 int vtkOpenGLPainterDeviceAdapter::QueryBlending()
942 {
943 VTK_LEGACY_BODY(vtkOpenGLPainterDeviceAdapter::QueryBlending, "VTK 6.1");
944 if (glIsEnabled(GL_BLEND))
945 {
946 return 1;
947 }
948 else
949 {
950 return 0;
951 }
952 }
953 #endif
954
955 //-----------------------------------------------------------------------------
MakeVertexEmphasis(bool mode)956 void vtkOpenGLPainterDeviceAdapter::MakeVertexEmphasis(bool mode)
957 {
958 if (mode)
959 {
960 float s;
961 glGetFloatv(GL_POINT_SIZE, &s);
962 this->PointSize = s;
963 glPointSize(4.0); //make verts large enough to be sure to overlap cell
964 vtkOpenGLGL2PSHelper::SetPointSize(4.0);
965
966 float nf[2]; //put verts just in front of associated cells
967 glGetFloatv(GL_DEPTH_RANGE, nf);
968 this->RangeNear = nf[0];
969 this->RangeFar = nf[1];
970 glDepthRange(0.0, nf[1]*0.999999);
971 glDepthMask(GL_FALSE); //prevent verts from interfering with each other
972 }
973 else
974 {
975 glPointSize(static_cast<GLfloat>(this->PointSize));
976 vtkOpenGLGL2PSHelper::SetPointSize(static_cast<GLfloat>(this->PointSize));
977 glDepthRange(this->RangeNear, this->RangeFar);
978 glDepthMask(GL_TRUE);
979 }
980 vtkOpenGLCheckErrorMacro("failed after MakeVertexEmphasis");
981 }
982
983 //-----------------------------------------------------------------------------
WriteStencil(vtkIdType value)984 void vtkOpenGLPainterDeviceAdapter::WriteStencil(vtkIdType value)
985 {
986 if (this->MaxStencil)
987 {
988 value = value % this->MaxStencil + 1;
989 if (value == 1)
990 {
991 glClearStencil(0); //start over so don't write into some previous area
992 }
993 glStencilFunc(GL_ALWAYS, static_cast<GLint>(value), this->MaxStencil);
994 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
995 vtkOpenGLCheckErrorMacro("failed after WriteStencil");
996 }
997 }
998
999 //-----------------------------------------------------------------------------
TestStencil(vtkIdType value)1000 void vtkOpenGLPainterDeviceAdapter::TestStencil(vtkIdType value)
1001 {
1002 if (this->MaxStencil)
1003 {
1004 value = value % this->MaxStencil + 1;
1005 glStencilFunc(GL_EQUAL, static_cast<GLint>(value), this->MaxStencil);
1006 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1007 vtkOpenGLCheckErrorMacro("failed after TestStencil");
1008 }
1009 }
1010
1011 //-----------------------------------------------------------------------------
Stencil(int on)1012 void vtkOpenGLPainterDeviceAdapter::Stencil(int on)
1013 {
1014 if (on)
1015 {
1016 glEnable(GL_STENCIL_TEST);
1017 GLint stencilbits;
1018 glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
1019 this->MaxStencil = (1<<stencilbits)-1;
1020 }
1021 else
1022 {
1023 glDisable(GL_STENCIL_TEST);
1024 }
1025 vtkOpenGLCheckErrorMacro("failed after Stencil");
1026 }
1027
1028
1029