1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkOpenGLState.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 #include "vtkOpenGLState.h"
16 #include "vtk_glew.h"
17
18 #include "vtkObjectFactory.h"
19 #include "vtkOpenGLFramebufferObject.h"
20 #include "vtkOpenGLRenderUtilities.h"
21 #include "vtkOpenGLRenderWindow.h"
22 #include "vtkOpenGLShaderCache.h"
23 #include "vtkOpenGLVertexBufferObjectCache.h"
24 #include "vtkRenderer.h"
25 #include "vtkTextureUnitManager.h"
26
27 // must be included after a vtkObject subclass
28 #include "vtkOpenGLError.h"
29
30 #include <cmath>
31
32 #include "vtksys/SystemInformation.hxx"
33
34 // If you define NO_CACHE then all state->vtkgl* calls
35 // will get passed down to OpenGL regardless of the current
36 // state. This basically bypasses the caching mechanism
37 // and is useful for tesing
38 // #define NO_CACHE 1
39
40 //////////////////////////////////////////////////////////////////////////////
41 //
42 // if VTK_REPORT_OPENGL_ERRORS is defined (done in CMake and vtkOpenGLError.h)
43 // then a few things change here.
44 //
45 // 1) the error code of OpenGL will be checked after every call.
46 // 2) On an error the full stack trace available will be
47 // printed.
48 // 3) All methods check the cache state to see if anything is out of sync
49 //
50 // #undef VTK_REPORT_OPENGL_ERRORS
51 #ifdef VTK_REPORT_OPENGL_ERRORS
52
53 // this method checks all the cached state to make sure
54 // nothing is out of sync. It can be slow.
CheckState()55 void vtkOpenGLState::CheckState()
56 {
57 bool error = false;
58
59 vtkOpenGLRenderUtilities::MarkDebugEvent("Checking OpenGL State");
60
61 GLboolean params[4];
62
63 auto& cs = this->Stack.top();
64
65 ::glGetBooleanv(GL_DEPTH_WRITEMASK, params);
66 if (params[0] != cs.DepthMask)
67 {
68 vtkGenericWarningMacro("Error in cache state for GL_DEPTH_WRITEMASK");
69 this->ResetGLDepthMaskState();
70 error = true;
71 }
72 ::glGetBooleanv(GL_COLOR_WRITEMASK, params);
73 if (params[0] != cs.ColorMask[0] || params[1] != cs.ColorMask[1] ||
74 params[2] != cs.ColorMask[2] || params[3] != cs.ColorMask[3])
75 {
76 vtkGenericWarningMacro("Error in cache state for GL_COLOR_WRITEMASK");
77 this->ResetGLColorMaskState();
78 error = true;
79 }
80 ::glGetBooleanv(GL_BLEND, params);
81 if ((params[0] != 0) != cs.Blend)
82 {
83 vtkGenericWarningMacro("Error in cache state for GL_BLEND");
84 this->ResetEnumState(GL_BLEND);
85 error = true;
86 }
87 ::glGetBooleanv(GL_DEPTH_TEST, params);
88 if ((params[0] != 0) != cs.DepthTest)
89 {
90 vtkGenericWarningMacro("Error in cache state for GL_DEPTH_TEST");
91 this->ResetEnumState(GL_DEPTH_TEST);
92 error = true;
93 }
94 ::glGetBooleanv(GL_CULL_FACE, params);
95 if ((params[0] != 0) != cs.CullFace)
96 {
97 vtkGenericWarningMacro("Error in cache state for GL_CULL_FACE");
98 this->ResetEnumState(GL_CULL_FACE);
99 error = true;
100 }
101 #ifdef GL_MULTISAMPLE
102 ::glGetBooleanv(GL_MULTISAMPLE, params);
103 if ((params[0] != 0) != cs.MultiSample)
104 {
105 vtkGenericWarningMacro("Error in cache state for GL_MULTISAMPLE");
106 this->ResetEnumState(GL_MULTISAMPLE);
107 error = true;
108 }
109 #endif
110 ::glGetBooleanv(GL_SCISSOR_TEST, params);
111 if ((params[0] != 0) != cs.ScissorTest)
112 {
113 vtkGenericWarningMacro("Error in cache state for GL_SCISSOR_TEST");
114 this->ResetEnumState(GL_SCISSOR_TEST);
115 error = true;
116 }
117 ::glGetBooleanv(GL_STENCIL_TEST, params);
118 if ((params[0] != 0) != cs.StencilTest)
119 {
120 vtkGenericWarningMacro("Error in cache state for GL_STENCIL_TEST");
121 this->ResetEnumState(GL_STENCIL_TEST);
122 error = true;
123 }
124 #ifdef GL_TEXTURE_CUBE_MAP_SEAMLESS
125 ::glGetBooleanv(GL_TEXTURE_CUBE_MAP_SEAMLESS, params);
126 if ((params[0] != 0) != cs.CubeMapSeamless)
127 {
128 vtkGenericWarningMacro("Error in cache state for GL_TEXTURE_CUBE_MAP_SEAMLESS");
129 this->ResetEnumState(GL_TEXTURE_CUBE_MAP_SEAMLESS);
130 error = true;
131 }
132 #endif
133
134 GLint iparams[4];
135 #if defined(__APPLE__)
136 // OSX systems seem to change the glViewport upon a window resize
137 // under the hood, so our viewport cache cannot be trusted
138 this->ResetGLViewportState();
139 #endif
140 ::glGetIntegerv(GL_VIEWPORT, iparams);
141 if (iparams[0] != cs.Viewport[0] || iparams[1] != cs.Viewport[1] ||
142 iparams[2] != cs.Viewport[2] || iparams[3] != cs.Viewport[3])
143 {
144 vtkGenericWarningMacro("Error in cache state for GL_VIEWPORT");
145 this->ResetGLViewportState();
146 error = true;
147 }
148 ::glGetIntegerv(GL_SCISSOR_BOX, iparams);
149 if (iparams[0] != cs.Scissor[0] || iparams[1] != cs.Scissor[1] || iparams[2] != cs.Scissor[2] ||
150 iparams[3] != cs.Scissor[3])
151 {
152 vtkGenericWarningMacro("Error in cache state for GL_SCISSOR_BOX");
153 this->ResetGLScissorState();
154 error = true;
155 }
156 ::glGetIntegerv(GL_CULL_FACE_MODE, iparams);
157 if (iparams[0] != static_cast<int>(cs.CullFaceMode))
158 {
159 vtkGenericWarningMacro("Error in cache state for GL_CULL_FACE_MODE");
160 this->ResetGLCullFaceState();
161 error = true;
162 }
163 ::glGetIntegerv(GL_ACTIVE_TEXTURE, iparams);
164 if (iparams[0] != static_cast<int>(cs.ActiveTexture))
165 {
166 vtkGenericWarningMacro("Error in cache state for GL_ACTIVE_TEXTURE");
167 this->ResetGLActiveTexture();
168 error = true;
169 }
170 ::glGetIntegerv(GL_DEPTH_FUNC, iparams);
171 if (iparams[0] != static_cast<int>(cs.DepthFunc))
172 {
173 vtkGenericWarningMacro("Error in cache state for GL_DEPTH_FUNC");
174 this->ResetGLDepthFuncState();
175 error = true;
176 }
177 ::glGetIntegerv(GL_BLEND_SRC_RGB, iparams);
178 if (iparams[0] != static_cast<int>(cs.BlendFunc[0]))
179 {
180 vtkGenericWarningMacro("Error in cache state for GL_BLEND_SRC_RGB");
181 this->ResetGLBlendFuncState();
182 error = true;
183 }
184 ::glGetIntegerv(GL_BLEND_SRC_ALPHA, iparams);
185 if (iparams[0] != static_cast<int>(cs.BlendFunc[2]))
186 {
187 vtkGenericWarningMacro("Error in cache state for GL_BLEND_SRC_ALPHA");
188 this->ResetGLBlendFuncState();
189 error = true;
190 }
191 ::glGetIntegerv(GL_BLEND_DST_RGB, iparams);
192 if (iparams[0] != static_cast<int>(cs.BlendFunc[1]))
193 {
194 vtkGenericWarningMacro("Error in cache state for GL_BLEND_DST_RGB");
195 this->ResetGLBlendFuncState();
196 error = true;
197 }
198 ::glGetIntegerv(GL_BLEND_DST_ALPHA, iparams);
199 if (iparams[0] != static_cast<int>(cs.BlendFunc[3]))
200 {
201 vtkGenericWarningMacro("Error in cache state for GL_BLEND_DST_ALPHA");
202 this->ResetGLBlendFuncState();
203 error = true;
204 }
205 ::glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, iparams);
206 if (iparams[0] != static_cast<int>(cs.DrawBinding.GetBinding()))
207 {
208 vtkGenericWarningMacro("Error in cache state for GL_DRAW_FRAMEBUFFER_BINDING");
209 this->ResetFramebufferBindings();
210 error = true;
211 }
212 ::glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, iparams);
213 if (iparams[0] != static_cast<int>(cs.ReadBinding.GetBinding()))
214 {
215 vtkGenericWarningMacro("Error in cache state for GL_READ_FRAMEBUFFER_BINDING");
216 this->ResetFramebufferBindings();
217 error = true;
218 }
219 unsigned int sval;
220 #ifdef GL_DRAW_BUFFER
221 ::glGetIntegerv(GL_DRAW_BUFFER, iparams);
222 sval = cs.DrawBinding.GetDrawBuffer(0);
223 if (sval == GL_BACK_LEFT)
224 {
225 sval = GL_BACK;
226 }
227 if (iparams[0] == GL_BACK_LEFT)
228 {
229 iparams[0] = GL_BACK;
230 }
231 if (iparams[0] != static_cast<int>(sval))
232 {
233 vtkGenericWarningMacro("Error in cache state for GL_DRAW_BUFFER got "
234 << iparams[0] << " expected" << cs.DrawBinding.GetDrawBuffer(0));
235 this->ResetFramebufferBindings();
236 error = true;
237 }
238 #endif
239 ::glGetIntegerv(GL_READ_BUFFER, iparams);
240 sval = cs.ReadBinding.GetReadBuffer();
241 // handle odd left right stuff
242 if (sval == GL_BACK_LEFT)
243 {
244 sval = GL_BACK;
245 }
246 if (iparams[0] == GL_BACK_LEFT)
247 {
248 iparams[0] = GL_BACK;
249 }
250 if (iparams[0] != static_cast<int>(sval))
251 {
252 vtkGenericWarningMacro("Error in cache state for GL_READ_BUFFER");
253 this->ResetFramebufferBindings();
254 error = true;
255 }
256
257 GLfloat fparams[4];
258 // note people do set this to nan
259 ::glGetFloatv(GL_COLOR_CLEAR_VALUE, fparams);
260 if ((!(std::isnan(fparams[0]) && std::isnan(cs.ClearColor[0])) &&
261 fparams[0] != cs.ClearColor[0]) ||
262 (!(std::isnan(fparams[1]) && std::isnan(cs.ClearColor[1])) && fparams[1] != cs.ClearColor[1]) ||
263 (!(std::isnan(fparams[2]) && std::isnan(cs.ClearColor[2])) && fparams[2] != cs.ClearColor[2]) ||
264 (!(std::isnan(fparams[3]) && std::isnan(cs.ClearColor[3])) && fparams[3] != cs.ClearColor[3]))
265 {
266 vtkGenericWarningMacro("Error in cache state for GL_COLOR_CLEAR_VALUE");
267 this->ResetGLClearColorState();
268 error = true;
269 }
270
271 if (error)
272 {
273 std::string msg = vtksys::SystemInformation::GetProgramStack(0, 0);
274 vtkGenericWarningMacro("at stack loc\n" << msg);
275 }
276 vtkOpenGLRenderUtilities::MarkDebugEvent("Finished Checking OpenGL State");
277 }
278
279 namespace
280 {
reportOpenGLErrors(std::string & result)281 bool reportOpenGLErrors(std::string& result)
282 {
283 const int maxErrors = 16;
284 unsigned int errCode[maxErrors] = { 0 };
285 const char* errDesc[maxErrors] = { nullptr };
286
287 int numErrors = vtkGetOpenGLErrors(maxErrors, errCode, errDesc);
288
289 if (numErrors)
290 {
291 std::ostringstream oss;
292 vtkPrintOpenGLErrors(oss, maxErrors, numErrors, errCode, errDesc);
293
294 oss << "\n with stack trace of\n" << vtksys::SystemInformation::GetProgramStack(0, 0);
295 result = oss.str();
296 return true;
297 }
298 return false;
299 }
300
301 } // anon namespace
302
303 #define vtkOpenGLCheckStateMacro() this->CheckState()
304
305 #define vtkCheckOpenGLErrorsWithStack(message) \
306 { \
307 std::string _tmp; \
308 if (reportOpenGLErrors(_tmp)) \
309 { \
310 vtkGenericWarningMacro("Error " << message << _tmp); \
311 vtkOpenGLClearErrorMacro(); \
312 } \
313 }
314
315 #else // VTK_REPORT_OPENGL_ERRORS
316
317 #define vtkCheckOpenGLErrorsWithStack(message)
318 #define vtkOpenGLCheckStateMacro()
319
320 #endif // VTK_REPORT_OPENGL_ERRORS
321
322 //
323 //////////////////////////////////////////////////////////////////////////////
324
BufferBindingState()325 vtkOpenGLState::BufferBindingState::BufferBindingState()
326 {
327 // this->Framebuffer = nullptr;
328 this->ReadBuffer = GL_NONE;
329 this->DrawBuffers[0] = GL_BACK;
330 }
331
332 // bool vtkOpenGLState::BufferBindingState::operator==(
333 // const BufferBindingState& a, const BufferBindingState& b)
334 // {
335 // return a.Framebuffer == b.Framebuffer &&
336 // }
337
GetBinding()338 unsigned int vtkOpenGLState::BufferBindingState::GetBinding()
339 {
340 // if (this->Framebuffer)
341 // {
342 // return this->Framebuffer->GetFBOIndex();
343 // }
344 return this->Binding;
345 }
346
GetDrawBuffer(unsigned int val)347 unsigned int vtkOpenGLState::BufferBindingState::GetDrawBuffer(unsigned int val)
348 {
349 // if (this->Framebuffer)
350 // {
351 // return this->Framebuffer->GetActiveDrawBuffer(val);
352 // }
353 return this->DrawBuffers[val];
354 }
355
GetReadBuffer()356 unsigned int vtkOpenGLState::BufferBindingState::GetReadBuffer()
357 {
358 // if (this->Framebuffer)
359 // {
360 // return this->Framebuffer->GetActiveReadBuffer();
361 // }
362 return this->ReadBuffer;
363 }
364
ScopedglDepthMask(vtkOpenGLState * s)365 vtkOpenGLState::ScopedglDepthMask::ScopedglDepthMask(vtkOpenGLState* s)
366 {
367 this->State = s;
368 this->Value = this->State->Stack.top().DepthMask;
369 this->Method = &vtkOpenGLState::vtkglDepthMask;
370 }
371
ScopedglColorMask(vtkOpenGLState * s)372 vtkOpenGLState::ScopedglColorMask::ScopedglColorMask(vtkOpenGLState* s)
373 {
374 this->State = s;
375 this->Value = this->State->Stack.top().ColorMask;
376 this->Method = &vtkOpenGLState::ColorMask;
377 }
378
ScopedglDepthFunc(vtkOpenGLState * s)379 vtkOpenGLState::ScopedglDepthFunc::ScopedglDepthFunc(vtkOpenGLState* s)
380 {
381 this->State = s;
382 this->Value = this->State->Stack.top().DepthFunc;
383 this->Method = &vtkOpenGLState::vtkglDepthFunc;
384 }
385
ScopedglClearColor(vtkOpenGLState * s)386 vtkOpenGLState::ScopedglClearColor::ScopedglClearColor(vtkOpenGLState* s)
387 {
388 this->State = s;
389 this->Value = this->State->Stack.top().ClearColor;
390 this->Method = &vtkOpenGLState::ClearColor;
391 }
392
ScopedglScissor(vtkOpenGLState * s)393 vtkOpenGLState::ScopedglScissor::ScopedglScissor(vtkOpenGLState* s)
394 {
395 this->State = s;
396 this->Value = this->State->Stack.top().Scissor;
397 this->Method = &vtkOpenGLState::Scissor;
398 }
399
ScopedglViewport(vtkOpenGLState * s)400 vtkOpenGLState::ScopedglViewport::ScopedglViewport(vtkOpenGLState* s)
401 {
402 this->State = s;
403 this->Value = this->State->Stack.top().Viewport;
404 this->Method = &vtkOpenGLState::Viewport;
405 }
406
ScopedglBlendFuncSeparate(vtkOpenGLState * s)407 vtkOpenGLState::ScopedglBlendFuncSeparate::ScopedglBlendFuncSeparate(vtkOpenGLState* s)
408 {
409 this->State = s;
410 this->Value = this->State->Stack.top().BlendFunc;
411 this->Method = &vtkOpenGLState::BlendFuncSeparate;
412 }
413
ScopedglActiveTexture(vtkOpenGLState * s)414 vtkOpenGLState::ScopedglActiveTexture::ScopedglActiveTexture(vtkOpenGLState* s)
415 {
416 this->State = s;
417 this->Value = this->State->Stack.top().ActiveTexture;
418 this->Method = &vtkOpenGLState::vtkglActiveTexture;
419 }
420
ColorMask(std::array<GLboolean,4> val)421 void vtkOpenGLState::ColorMask(std::array<GLboolean, 4> val)
422 {
423 this->vtkglColorMask(val[0], val[1], val[2], val[3]);
424 }
425
vtkglColorMask(GLboolean r,GLboolean g,GLboolean b,GLboolean a)426 void vtkOpenGLState::vtkglColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a)
427 {
428 vtkOpenGLCheckStateMacro();
429 auto& cs = this->Stack.top();
430
431 #ifndef NO_CACHE
432 if (cs.ColorMask[0] != r || cs.ColorMask[1] != g || cs.ColorMask[2] != b || cs.ColorMask[3] != a)
433 #endif
434 {
435 cs.ColorMask[0] = r;
436 cs.ColorMask[1] = g;
437 cs.ColorMask[2] = b;
438 cs.ColorMask[3] = a;
439 ::glColorMask(r, g, b, a);
440 }
441
442 vtkCheckOpenGLErrorsWithStack("glColorMask");
443 }
444
ClearColor(std::array<GLclampf,4> val)445 void vtkOpenGLState::ClearColor(std::array<GLclampf, 4> val)
446 {
447 this->vtkglClearColor(val[0], val[1], val[2], val[3]);
448 }
449
vtkglClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)450 void vtkOpenGLState::vtkglClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
451 {
452 vtkOpenGLCheckStateMacro();
453 auto& cs = this->Stack.top();
454
455 #ifndef NO_CACHE
456 if (cs.ClearColor[0] != red || cs.ClearColor[1] != green || cs.ClearColor[2] != blue ||
457 cs.ClearColor[3] != alpha)
458 #endif
459 {
460 cs.ClearColor[0] = red;
461 cs.ClearColor[1] = green;
462 cs.ClearColor[2] = blue;
463 cs.ClearColor[3] = alpha;
464 ::glClearColor(red, green, blue, alpha);
465 }
466
467 vtkCheckOpenGLErrorsWithStack("glClearColor");
468 }
469
vtkglClearDepth(double val)470 void vtkOpenGLState::vtkglClearDepth(double val)
471 {
472 vtkOpenGLCheckStateMacro();
473 auto& cs = this->Stack.top();
474
475 #ifndef NO_CACHE
476 if (cs.ClearDepth != val)
477 #endif
478 {
479 cs.ClearDepth = val;
480 #ifdef GL_ES_VERSION_3_0
481 ::glClearDepthf(static_cast<GLclampf>(val));
482 #else
483 ::glClearDepth(val);
484 #endif
485 }
486 vtkCheckOpenGLErrorsWithStack("glClearDepth");
487 }
488
vtkBindFramebuffer(unsigned int target,vtkOpenGLFramebufferObject * fo)489 void vtkOpenGLState::vtkBindFramebuffer(unsigned int target, vtkOpenGLFramebufferObject* fo)
490 {
491 this->vtkglBindFramebuffer(target, fo ? fo->GetFBOIndex() : 0);
492 }
493
vtkglBindFramebuffer(unsigned int target,unsigned int val)494 void vtkOpenGLState::vtkglBindFramebuffer(unsigned int target, unsigned int val)
495 {
496 vtkOpenGLCheckStateMacro();
497 auto& cs = this->Stack.top();
498
499 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
500 {
501 #ifndef NO_CACHE
502 if (cs.DrawBinding.Binding != val)
503 #endif
504 {
505 cs.DrawBinding.Binding = val;
506 ::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, val);
507 #ifdef GL_DRAW_BUFFER
508 ::glGetIntegerv(GL_DRAW_BUFFER, (int*)&cs.DrawBinding.DrawBuffers[0]);
509 #endif
510 }
511 }
512
513 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
514 {
515 #ifndef NO_CACHE
516 if (cs.ReadBinding.Binding != val)
517 #endif
518 {
519 cs.ReadBinding.Binding = val;
520 ::glBindFramebuffer(GL_READ_FRAMEBUFFER, val);
521 ::glGetIntegerv(GL_READ_BUFFER, (int*)&cs.ReadBinding.ReadBuffer);
522 }
523 }
524
525 vtkCheckOpenGLErrorsWithStack("glBindFramebuffer");
526 }
527
vtkglDrawBuffer(unsigned int val)528 void vtkOpenGLState::vtkglDrawBuffer(unsigned int val)
529 {
530 vtkOpenGLCheckStateMacro();
531 auto& cs = this->Stack.top();
532
533 if (cs.DrawBinding.Binding && val < GL_COLOR_ATTACHMENT0 && val != GL_NONE)
534 {
535 // todo get rid of the && and make this always an error if FO is set
536 vtkGenericWarningMacro(
537 "A vtkOpenGLFramebufferObject is currently bound but a hardware draw buffer was requested.");
538 std::string msg = vtksys::SystemInformation::GetProgramStack(0, 0);
539 vtkGenericWarningMacro("at stack loc\n" << msg);
540 }
541
542 #ifndef NO_CACHE
543 if (cs.DrawBinding.DrawBuffers[0] != val)
544 #endif
545 {
546 cs.DrawBinding.DrawBuffers[0] = val;
547 ::glDrawBuffers(1, cs.DrawBinding.DrawBuffers);
548 }
549
550 // change all stack entries for the same framebuffer
551 for (auto& se : this->DrawBindings)
552 {
553 if (se.Binding == cs.DrawBinding.Binding)
554 {
555 se.DrawBuffers[0] = val;
556 }
557 }
558
559 vtkCheckOpenGLErrorsWithStack("glDrawBuffer");
560 }
561
vtkglDrawBuffers(unsigned int count,unsigned int * vals)562 void vtkOpenGLState::vtkglDrawBuffers(unsigned int count, unsigned int* vals)
563 {
564 vtkOpenGLCheckStateMacro();
565
566 if (count <= 0)
567 {
568 return;
569 }
570
571 auto& cs = this->Stack.top();
572 if (cs.DrawBinding.Binding && vals[0] < GL_COLOR_ATTACHMENT0 && vals[0] != GL_NONE)
573 {
574 // todo get rid of the && and make this always an error if FO is set
575 vtkGenericWarningMacro(
576 "A vtkOpenGLFramebufferObject is currently bound but hardware draw buffers were requested.");
577 }
578
579 #ifndef NO_CACHE
580 bool changed = false;
581 for (int i = 0; i < static_cast<int>(count) && i < 10; ++i)
582 {
583 if (vals[i] != cs.DrawBinding.DrawBuffers[i])
584 {
585 changed = true;
586 }
587 }
588 if (count > 10)
589 {
590 changed = true;
591 }
592 if (changed)
593 #endif
594 {
595 for (unsigned int i = 0; i < count && i < 10; ++i)
596 {
597 cs.DrawBinding.DrawBuffers[i] = vals[i];
598 }
599 ::glDrawBuffers(count, vals);
600 }
601
602 // change all stack entries for the same framebuffer
603 for (auto& se : this->DrawBindings)
604 {
605 if (se.Binding == cs.DrawBinding.Binding)
606 {
607 for (unsigned int i = 0; i < count && i < 10; ++i)
608 {
609 se.DrawBuffers[i] = vals[i];
610 }
611 }
612 }
613
614 vtkCheckOpenGLErrorsWithStack("glDrawBuffers");
615 }
616
vtkDrawBuffers(unsigned int count,unsigned int * vals,vtkOpenGLFramebufferObject * fo)617 void vtkOpenGLState::vtkDrawBuffers(
618 unsigned int count, unsigned int* vals, vtkOpenGLFramebufferObject* fo)
619 {
620 vtkOpenGLCheckStateMacro();
621
622 if (count <= 0)
623 {
624 return;
625 }
626
627 auto& cs = this->Stack.top();
628 if (fo->GetFBOIndex() != cs.DrawBinding.Binding)
629 {
630 vtkGenericWarningMacro(
631 "Attempt to set draw buffers from a Framebuffer Object that is not bound.");
632 }
633
634 this->vtkglDrawBuffers(count, vals);
635 }
636
vtkglReadBuffer(unsigned int val)637 void vtkOpenGLState::vtkglReadBuffer(unsigned int val)
638 {
639 vtkOpenGLCheckStateMacro();
640 auto& cs = this->Stack.top();
641
642 if (cs.ReadBinding.Binding && val < GL_COLOR_ATTACHMENT0 && val != GL_NONE)
643 {
644 vtkGenericWarningMacro(
645 "A vtkOpenGLFramebufferObject is currently bound but a hardware read buffer was requested.");
646 }
647
648 #ifndef NO_CACHE
649 if (cs.ReadBinding.ReadBuffer != val)
650 #endif
651 {
652 cs.ReadBinding.ReadBuffer = val;
653 ::glReadBuffer(val);
654 }
655
656 // change all stack entries for the same framebuffer
657 for (auto& se : this->ReadBindings)
658 {
659 if (se.Binding == cs.ReadBinding.Binding)
660 {
661 se.ReadBuffer = val;
662 }
663 }
664
665 vtkCheckOpenGLErrorsWithStack("glReadBuffer");
666 }
667
vtkReadBuffer(unsigned int val,vtkOpenGLFramebufferObject * fo)668 void vtkOpenGLState::vtkReadBuffer(unsigned int val, vtkOpenGLFramebufferObject* fo)
669 {
670 vtkOpenGLCheckStateMacro();
671 auto& cs = this->Stack.top();
672
673 if (fo->GetFBOIndex() != cs.ReadBinding.Binding)
674 {
675 vtkGenericWarningMacro(
676 "Attempt to set read buffer from a Framebuffer Object that is not bound.");
677 }
678
679 this->vtkglReadBuffer(val);
680 }
681
vtkglDepthFunc(GLenum val)682 void vtkOpenGLState::vtkglDepthFunc(GLenum val)
683 {
684 vtkOpenGLCheckStateMacro();
685 auto& cs = this->Stack.top();
686
687 #ifndef NO_CACHE
688 if (cs.DepthFunc != val)
689 #endif
690 {
691 cs.DepthFunc = val;
692 ::glDepthFunc(val);
693 }
694 vtkCheckOpenGLErrorsWithStack("glDepthFunc");
695 }
696
vtkglDepthMask(GLboolean val)697 void vtkOpenGLState::vtkglDepthMask(GLboolean val)
698 {
699 vtkOpenGLCheckStateMacro();
700 auto& cs = this->Stack.top();
701
702 #ifndef NO_CACHE
703 if (cs.DepthMask != val)
704 #endif
705 {
706 cs.DepthMask = val;
707 ::glDepthMask(val);
708 }
709 vtkCheckOpenGLErrorsWithStack("glDepthMask");
710 }
711
vtkglPointSize(GLfloat val)712 void vtkOpenGLState::vtkglPointSize(GLfloat val)
713 {
714 vtkOpenGLCheckStateMacro();
715 auto& cs = this->Stack.top();
716
717 #ifndef NO_CACHE
718 if (cs.PointSize != val)
719 #endif
720 {
721 cs.PointSize = val;
722 #ifndef GL_ES_VERSION_3_0
723 ::glPointSize(val);
724 #endif
725 }
726 vtkCheckOpenGLErrorsWithStack("glPointSize");
727 }
728
vtkglLineWidth(GLfloat val)729 void vtkOpenGLState::vtkglLineWidth(GLfloat val)
730 {
731 vtkOpenGLCheckStateMacro();
732 auto& cs = this->Stack.top();
733
734 #ifndef NO_CACHE
735 if (cs.LineWidth != val)
736 #endif
737 {
738 cs.LineWidth = val;
739 ::glLineWidth(val);
740 }
741 vtkCheckOpenGLErrorsWithStack("glLineWidth");
742 }
743
vtkglStencilMask(GLuint mask)744 void vtkOpenGLState::vtkglStencilMask(GLuint mask)
745 {
746 this->vtkglStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
747 }
748
vtkglStencilMaskSeparate(GLuint face,GLuint mask)749 void vtkOpenGLState::vtkglStencilMaskSeparate(GLuint face, GLuint mask)
750 {
751 vtkOpenGLCheckStateMacro();
752 auto& cs = this->Stack.top();
753
754 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
755 {
756 #ifndef NO_CACHE
757 if (cs.StencilMaskFront != mask)
758 #endif
759 {
760 cs.StencilMaskFront = mask;
761 ::glStencilMaskSeparate(GL_FRONT, mask);
762 }
763 }
764
765 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
766 {
767 #ifndef NO_CACHE
768 if (cs.StencilMaskBack != mask)
769 #endif
770 {
771 cs.StencilMaskBack = mask;
772 ::glStencilMaskSeparate(GL_BACK, mask);
773 }
774 }
775
776 vtkCheckOpenGLErrorsWithStack("glStencilMaskSeparate");
777 }
778
vtkglStencilOp(GLuint sfail,GLuint dpfail,GLuint dppass)779 void vtkOpenGLState::vtkglStencilOp(GLuint sfail, GLuint dpfail, GLuint dppass)
780 {
781 this->vtkglStencilOpSeparate(GL_FRONT_AND_BACK, sfail, dpfail, dppass);
782 }
783
vtkglStencilOpSeparate(GLuint face,GLuint sfail,GLuint dpfail,GLuint dppass)784 void vtkOpenGLState::vtkglStencilOpSeparate(GLuint face, GLuint sfail, GLuint dpfail, GLuint dppass)
785 {
786 vtkOpenGLCheckStateMacro();
787 auto& cs = this->Stack.top();
788
789 std::array<unsigned int, 3> vals = { sfail, dpfail, dppass };
790
791 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
792 {
793 #ifndef NO_CACHE
794 if (cs.StencilOpFront != vals)
795 #endif
796 {
797 cs.StencilOpFront = vals;
798 ::glStencilOpSeparate(GL_FRONT, vals[0], vals[1], vals[2]);
799 }
800 }
801
802 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
803 {
804 #ifndef NO_CACHE
805 if (cs.StencilOpBack != vals)
806 #endif
807 {
808 cs.StencilOpBack = vals;
809 ::glStencilOpSeparate(GL_BACK, vals[0], vals[1], vals[2]);
810 }
811 }
812
813 vtkCheckOpenGLErrorsWithStack("glStencilOpSeparate");
814 }
815
vtkglStencilFunc(GLuint func,GLint ref,GLuint mask)816 void vtkOpenGLState::vtkglStencilFunc(GLuint func, GLint ref, GLuint mask)
817 {
818 this->vtkglStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
819 }
820
vtkglStencilFuncSeparate(unsigned int face,unsigned int func,int ref,unsigned int mask)821 void vtkOpenGLState::vtkglStencilFuncSeparate(
822 unsigned int face, unsigned int func, int ref, unsigned int mask)
823 {
824 vtkOpenGLCheckStateMacro();
825 auto& cs = this->Stack.top();
826
827 std::array<unsigned int, 3> vals = { func, static_cast<unsigned int>(ref), mask };
828
829 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
830 {
831 #ifndef NO_CACHE
832 if (cs.StencilFuncFront != vals)
833 #endif
834 {
835 cs.StencilFuncFront = vals;
836 ::glStencilFuncSeparate(GL_FRONT, vals[0], static_cast<GLint>(vals[1]), vals[2]);
837 }
838 }
839
840 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
841 {
842 #ifndef NO_CACHE
843 if (cs.StencilFuncBack != vals)
844 #endif
845 {
846 cs.StencilFuncBack = vals;
847 ::glStencilFuncSeparate(GL_BACK, vals[0], static_cast<GLint>(vals[1]), vals[2]);
848 }
849 }
850
851 vtkCheckOpenGLErrorsWithStack("glStencilFuncSeparate");
852 }
853
BlendFuncSeparate(std::array<GLenum,4> val)854 void vtkOpenGLState::BlendFuncSeparate(std::array<GLenum, 4> val)
855 {
856 this->vtkglBlendFuncSeparate(val[0], val[1], val[2], val[3]);
857 }
858
vtkglBlendFuncSeparate(GLenum val1,GLenum val2,GLenum val3,GLenum val4)859 void vtkOpenGLState::vtkglBlendFuncSeparate(GLenum val1, GLenum val2, GLenum val3, GLenum val4)
860 {
861 vtkOpenGLCheckStateMacro();
862 auto& cs = this->Stack.top();
863
864 #ifndef NO_CACHE
865 if (cs.BlendFunc[0] != val1 || cs.BlendFunc[1] != val2 || cs.BlendFunc[2] != val3 ||
866 cs.BlendFunc[3] != val4)
867 #endif
868 {
869 cs.BlendFunc[0] = val1;
870 cs.BlendFunc[1] = val2;
871 cs.BlendFunc[2] = val3;
872 cs.BlendFunc[3] = val4;
873 ::glBlendFuncSeparate(val1, val2, val3, val4);
874 }
875 vtkCheckOpenGLErrorsWithStack("glBlendFuncSeparate");
876 }
877
vtkglBlendEquation(GLenum val)878 void vtkOpenGLState::vtkglBlendEquation(GLenum val)
879 {
880 this->vtkglBlendEquationSeparate(val, val);
881 }
882
vtkglBlendEquationSeparate(GLenum val,GLenum val2)883 void vtkOpenGLState::vtkglBlendEquationSeparate(GLenum val, GLenum val2)
884 {
885 vtkOpenGLCheckStateMacro();
886 auto& cs = this->Stack.top();
887
888 #ifndef NO_CACHE
889 if (cs.BlendEquationValue1 != val || cs.BlendEquationValue2 != val2)
890 #endif
891 {
892 cs.BlendEquationValue1 = val;
893 cs.BlendEquationValue2 = val2;
894 ::glBlendEquationSeparate(val, val2);
895 }
896
897 vtkCheckOpenGLErrorsWithStack("glBlendEquationSeparate");
898 }
899
vtkglCullFace(GLenum val)900 void vtkOpenGLState::vtkglCullFace(GLenum val)
901 {
902 vtkOpenGLCheckStateMacro();
903 auto& cs = this->Stack.top();
904
905 #ifndef NO_CACHE
906 if (cs.CullFaceMode != val)
907 #endif
908 {
909 cs.CullFaceMode = val;
910 ::glCullFace(val);
911 }
912 vtkCheckOpenGLErrorsWithStack("glCullFace");
913 }
914
vtkglActiveTexture(unsigned int val)915 void vtkOpenGLState::vtkglActiveTexture(unsigned int val)
916 {
917 vtkOpenGLCheckStateMacro();
918 auto& cs = this->Stack.top();
919
920 #ifndef NO_CACHE
921 if (cs.ActiveTexture != val)
922 #endif
923 {
924 cs.ActiveTexture = val;
925 ::glActiveTexture(val);
926 }
927 vtkCheckOpenGLErrorsWithStack("glActiveTexture");
928 }
929
Viewport(std::array<GLint,4> val)930 void vtkOpenGLState::Viewport(std::array<GLint, 4> val)
931 {
932 this->vtkglViewport(val[0], val[1], val[2], val[3]);
933 }
934
vtkglViewport(GLint x,GLint y,GLsizei width,GLsizei height)935 void vtkOpenGLState::vtkglViewport(GLint x, GLint y, GLsizei width, GLsizei height)
936 {
937 vtkOpenGLCheckStateMacro();
938 auto& cs = this->Stack.top();
939
940 #if !defined(NO_CACHE) && !defined(__APPLE__)
941 if (cs.Viewport[0] != x || cs.Viewport[1] != y || cs.Viewport[2] != width ||
942 cs.Viewport[3] != height)
943 #endif
944 {
945 cs.Viewport[0] = x;
946 cs.Viewport[1] = y;
947 cs.Viewport[2] = width;
948 cs.Viewport[3] = height;
949 ::glViewport(x, y, width, height);
950 }
951
952 vtkCheckOpenGLErrorsWithStack("glViewport");
953 }
954
Scissor(std::array<GLint,4> val)955 void vtkOpenGLState::Scissor(std::array<GLint, 4> val)
956 {
957 this->vtkglScissor(val[0], val[1], val[2], val[3]);
958 }
959
vtkglScissor(GLint x,GLint y,GLsizei width,GLsizei height)960 void vtkOpenGLState::vtkglScissor(GLint x, GLint y, GLsizei width, GLsizei height)
961 {
962 vtkOpenGLCheckStateMacro();
963 auto& cs = this->Stack.top();
964
965 #ifndef NO_CACHE
966 if (cs.Scissor[0] != x || cs.Scissor[1] != y || cs.Scissor[2] != width || cs.Scissor[3] != height)
967 #endif
968 {
969 cs.Scissor[0] = x;
970 cs.Scissor[1] = y;
971 cs.Scissor[2] = width;
972 cs.Scissor[3] = height;
973 ::glScissor(x, y, width, height);
974 }
975 vtkCheckOpenGLErrorsWithStack("glScissor");
976 }
977
SetEnumState(GLenum cap,bool val)978 void vtkOpenGLState::SetEnumState(GLenum cap, bool val)
979 {
980 vtkOpenGLCheckStateMacro();
981 auto& cs = this->Stack.top();
982
983 #ifndef NO_CACHE
984 bool changed = false;
985 #else
986 bool changed = true;
987 #endif
988 switch (cap)
989 {
990 case GL_BLEND:
991 if (cs.Blend != val)
992 {
993 cs.Blend = val;
994 changed = true;
995 }
996 break;
997 case GL_CULL_FACE:
998 if (cs.CullFace != val)
999 {
1000 cs.CullFace = val;
1001 changed = true;
1002 }
1003 break;
1004 case GL_DEPTH_TEST:
1005 if (cs.DepthTest != val)
1006 {
1007 cs.DepthTest = val;
1008 changed = true;
1009 }
1010 break;
1011 #ifdef GL_LINE_SMOOTH
1012 case GL_LINE_SMOOTH:
1013 if (cs.LineSmooth != val)
1014 {
1015 cs.LineSmooth = val;
1016 changed = true;
1017 }
1018 break;
1019 #endif
1020 #ifdef GL_MULTISAMPLE
1021 case GL_MULTISAMPLE:
1022 if (cs.MultiSample != val)
1023 {
1024 cs.MultiSample = val;
1025 changed = true;
1026 }
1027 break;
1028 #endif
1029 case GL_SCISSOR_TEST:
1030 if (cs.ScissorTest != val)
1031 {
1032 cs.ScissorTest = val;
1033 changed = true;
1034 }
1035 break;
1036 case GL_STENCIL_TEST:
1037 if (cs.StencilTest != val)
1038 {
1039 cs.StencilTest = val;
1040 changed = true;
1041 }
1042 break;
1043 #ifdef GL_TEXTURE_CUBE_MAP_SEAMLESS
1044 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1045 if (cs.CubeMapSeamless != val)
1046 {
1047 cs.CubeMapSeamless = val;
1048 changed = true;
1049 }
1050 break;
1051 #endif
1052 default:
1053 changed = true;
1054 }
1055
1056 if (!changed)
1057 {
1058 return;
1059 }
1060
1061 if (val)
1062 {
1063 ::glEnable(cap);
1064 }
1065 else
1066 {
1067 ::glDisable(cap);
1068 }
1069 vtkCheckOpenGLErrorsWithStack("glEnable/Disable");
1070 }
1071
ResetEnumState(GLenum cap)1072 void vtkOpenGLState::ResetEnumState(GLenum cap)
1073 {
1074 GLboolean params;
1075 ::glGetBooleanv(cap, ¶ms);
1076 auto& cs = this->Stack.top();
1077
1078 switch (cap)
1079 {
1080 case GL_BLEND:
1081 cs.Blend = params != 0;
1082 break;
1083 case GL_CULL_FACE:
1084 cs.CullFace = params != 0;
1085 break;
1086 case GL_DEPTH_TEST:
1087 cs.DepthTest = params != 0;
1088 break;
1089 #ifdef GL_LINE_SMOOTH
1090 case GL_LINE_SMOOTH:
1091 cs.LineSmooth = params != 0;
1092 break;
1093 #endif
1094 #ifdef GL_MULTISAMPLE
1095 case GL_MULTISAMPLE:
1096 cs.MultiSample = params != 0;
1097 break;
1098 #endif
1099 case GL_SCISSOR_TEST:
1100 cs.ScissorTest = params != 0;
1101 break;
1102 case GL_STENCIL_TEST:
1103 cs.StencilTest = params != 0;
1104 break;
1105 #ifdef GL_TEXTURE_CUBE_MAP_SEAMLESS
1106 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1107 cs.CubeMapSeamless = params != 0;
1108 break;
1109 #endif
1110 default:
1111 break;
1112 }
1113 }
1114
vtkglEnable(GLenum cap)1115 void vtkOpenGLState::vtkglEnable(GLenum cap)
1116 {
1117 this->SetEnumState(cap, true);
1118 }
1119
1120 // return cached value if we have it
1121 // otherwise forward to opengl
vtkglGetBooleanv(GLenum pname,GLboolean * params)1122 void vtkOpenGLState::vtkglGetBooleanv(GLenum pname, GLboolean* params)
1123 {
1124 vtkOpenGLCheckStateMacro();
1125 auto& cs = this->Stack.top();
1126
1127 switch (pname)
1128 {
1129 case GL_DEPTH_WRITEMASK:
1130 *params = cs.DepthMask;
1131 break;
1132 case GL_COLOR_WRITEMASK:
1133 params[0] = cs.ColorMask[0];
1134 params[1] = cs.ColorMask[1];
1135 params[2] = cs.ColorMask[2];
1136 params[3] = cs.ColorMask[3];
1137 break;
1138 case GL_BLEND:
1139 *params = cs.Blend;
1140 break;
1141 case GL_CULL_FACE:
1142 *params = cs.CullFace;
1143 break;
1144 case GL_DEPTH_TEST:
1145 *params = cs.DepthTest;
1146 break;
1147 #ifdef GL_LINE_SMOOTH
1148 case GL_LINE_SMOOTH:
1149 *params = cs.LineSmooth;
1150 break;
1151 #endif
1152 #ifdef GL_MULTISAMPLE
1153 case GL_MULTISAMPLE:
1154 *params = cs.MultiSample;
1155 break;
1156 #endif
1157 case GL_SCISSOR_TEST:
1158 *params = cs.ScissorTest;
1159 break;
1160 case GL_STENCIL_TEST:
1161 *params = cs.StencilTest;
1162 break;
1163 #ifdef GL_TEXTURE_CUBE_MAP_SEAMLESS
1164 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1165 *params = cs.CubeMapSeamless;
1166 break;
1167 #endif
1168 default:
1169 ::glGetBooleanv(pname, params);
1170 }
1171 vtkCheckOpenGLErrorsWithStack("glGetBoolean");
1172 }
1173
vtkglGetIntegerv(GLenum pname,GLint * params)1174 void vtkOpenGLState::vtkglGetIntegerv(GLenum pname, GLint* params)
1175 {
1176 vtkOpenGLCheckStateMacro();
1177 auto& cs = this->Stack.top();
1178
1179 switch (pname)
1180 {
1181 case GL_VIEWPORT:
1182 params[0] = cs.Viewport[0];
1183 params[1] = cs.Viewport[1];
1184 params[2] = cs.Viewport[2];
1185 params[3] = cs.Viewport[3];
1186 break;
1187 case GL_SCISSOR_BOX:
1188 params[0] = cs.Scissor[0];
1189 params[1] = cs.Scissor[1];
1190 params[2] = cs.Scissor[2];
1191 params[3] = cs.Scissor[3];
1192 break;
1193 case GL_CULL_FACE_MODE:
1194 *params = cs.CullFaceMode;
1195 break;
1196 case GL_DEPTH_FUNC:
1197 *params = cs.DepthFunc;
1198 break;
1199 case GL_BLEND_SRC_RGB:
1200 *params = cs.BlendFunc[0];
1201 break;
1202 case GL_BLEND_SRC_ALPHA:
1203 *params = cs.BlendFunc[2];
1204 break;
1205 case GL_BLEND_DST_RGB:
1206 *params = cs.BlendFunc[1];
1207 break;
1208 case GL_BLEND_DST_ALPHA:
1209 *params = cs.BlendFunc[3];
1210 break;
1211 case GL_MAX_TEXTURE_SIZE:
1212 *params = this->MaxTextureSize;
1213 break;
1214 case GL_MAJOR_VERSION:
1215 *params = this->MajorVersion;
1216 break;
1217 case GL_MINOR_VERSION:
1218 *params = this->MinorVersion;
1219 break;
1220 default:
1221 ::glGetIntegerv(pname, params);
1222 }
1223
1224 vtkCheckOpenGLErrorsWithStack("glGetInteger");
1225 }
1226
1227 #ifdef GL_ES_VERSION_3_0
vtkglGetDoublev(GLenum pname,double *)1228 void vtkOpenGLState::vtkglGetDoublev(GLenum pname, double*)
1229 {
1230 vtkGenericWarningMacro("glGetDouble not supported on OpenGL ES, requested: " << pname);
1231 }
1232 #else
vtkglGetDoublev(GLenum pname,double * params)1233 void vtkOpenGLState::vtkglGetDoublev(GLenum pname, double* params)
1234 {
1235 vtkOpenGLCheckStateMacro();
1236 ::glGetDoublev(pname, params);
1237 vtkCheckOpenGLErrorsWithStack("glGetDouble");
1238 }
1239 #endif
1240
vtkglGetFloatv(GLenum pname,GLfloat * params)1241 void vtkOpenGLState::vtkglGetFloatv(GLenum pname, GLfloat* params)
1242 {
1243 vtkOpenGLCheckStateMacro();
1244 auto& cs = this->Stack.top();
1245
1246 switch (pname)
1247 {
1248 case GL_COLOR_CLEAR_VALUE:
1249 params[0] = cs.ClearColor[0];
1250 params[1] = cs.ClearColor[1];
1251 params[2] = cs.ClearColor[2];
1252 params[3] = cs.ClearColor[3];
1253 break;
1254 default:
1255 ::glGetFloatv(pname, params);
1256 }
1257 vtkCheckOpenGLErrorsWithStack("glGetFloat");
1258 }
1259
GetBlendFuncState(int * v)1260 void vtkOpenGLState::GetBlendFuncState(int* v)
1261 {
1262 auto& cs = this->Stack.top();
1263 v[0] = cs.BlendFunc[0];
1264 v[1] = cs.BlendFunc[1];
1265 v[2] = cs.BlendFunc[2];
1266 v[3] = cs.BlendFunc[3];
1267 }
1268
GetEnumState(GLenum cap)1269 bool vtkOpenGLState::GetEnumState(GLenum cap)
1270 {
1271 vtkOpenGLCheckStateMacro();
1272 auto& cs = this->Stack.top();
1273
1274 switch (cap)
1275 {
1276 case GL_BLEND:
1277 return cs.Blend;
1278 case GL_CULL_FACE:
1279 return cs.CullFace;
1280 case GL_DEPTH_TEST:
1281 return cs.DepthTest;
1282 #ifdef GL_LINE_SMOOTH
1283 case GL_LINE_SMOOTH:
1284 return cs.LineSmooth;
1285 #endif
1286 #ifdef GL_MULTISAMPLE
1287 case GL_MULTISAMPLE:
1288 return cs.MultiSample;
1289 #endif
1290 case GL_SCISSOR_TEST:
1291 return cs.ScissorTest;
1292 case GL_STENCIL_TEST:
1293 return cs.StencilTest;
1294 #ifdef GL_TEXTURE_CUBE_MAP_SEAMLESS
1295 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1296 return cs.CubeMapSeamless;
1297 #endif
1298 default:
1299 vtkGenericWarningMacro("Bad request for enum status");
1300 }
1301 return false;
1302 }
1303
vtkglDisable(GLenum cap)1304 void vtkOpenGLState::vtkglDisable(GLenum cap)
1305 {
1306 this->SetEnumState(cap, false);
1307 }
1308
vtkglPixelStorei(unsigned int cap,int val)1309 void vtkOpenGLState::vtkglPixelStorei(unsigned int cap, int val)
1310 {
1311 vtkOpenGLCheckStateMacro();
1312 auto& cs = this->Stack.top();
1313
1314 #ifndef NO_CACHE
1315 bool changed = false;
1316 #else
1317 bool changed = true;
1318 #endif
1319 switch (cap)
1320 {
1321 case GL_PACK_ALIGNMENT:
1322 if (cs.PackAlignment != val)
1323 {
1324 cs.PackAlignment = val;
1325 changed = true;
1326 }
1327 break;
1328 case GL_UNPACK_ALIGNMENT:
1329 if (cs.UnpackAlignment != val)
1330 {
1331 cs.UnpackAlignment = val;
1332 changed = true;
1333 }
1334 break;
1335 case GL_UNPACK_ROW_LENGTH:
1336 if (cs.UnpackRowLength != val)
1337 {
1338 cs.UnpackRowLength = val;
1339 changed = true;
1340 }
1341 break;
1342 case GL_UNPACK_IMAGE_HEIGHT:
1343 if (cs.UnpackImageHeight != val)
1344 {
1345 cs.UnpackImageHeight = val;
1346 changed = true;
1347 }
1348 break;
1349 default:
1350 changed = true;
1351 }
1352
1353 if (!changed)
1354 {
1355 return;
1356 }
1357
1358 ::glPixelStorei(cap, val);
1359 vtkCheckOpenGLErrorsWithStack("glPixelStorei");
1360 }
1361
1362 // make the recorded state match OpenGL driver
1363 // Initialize makes OpenGL match the state
1364 // This makes the state match OpenGL
Reset()1365 void vtkOpenGLState::Reset()
1366 {
1367 vtkOpenGLRenderUtilities::MarkDebugEvent("Resetting OpenGL State");
1368 this->ResetGLClearColorState();
1369 this->ResetGLClearDepthState();
1370 this->ResetGLDepthFuncState();
1371 this->ResetGLDepthMaskState();
1372 this->ResetGLColorMaskState();
1373 this->ResetGLViewportState();
1374 this->ResetGLScissorState();
1375 this->ResetGLBlendFuncState();
1376 this->ResetGLBlendEquationState();
1377 this->ResetGLCullFaceState();
1378 this->ResetGLActiveTexture();
1379 this->ResetFramebufferBindings();
1380
1381 this->ResetEnumState(GL_BLEND);
1382 this->ResetEnumState(GL_CULL_FACE);
1383 this->ResetEnumState(GL_DEPTH_TEST);
1384 #ifdef GL_LINE_SMOOTH
1385 this->ResetEnumState(GL_LINE_SMOOTH);
1386 #endif
1387 this->ResetEnumState(GL_STENCIL_TEST);
1388 this->ResetEnumState(GL_SCISSOR_TEST);
1389 #ifdef GL_TEXTURE_CUBE_MAP_SEAMLESS
1390 this->ResetEnumState(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1391 #endif
1392 #ifdef GL_MULTISAMPLE
1393 this->ResetEnumState(GL_MULTISAMPLE);
1394 #endif
1395
1396 auto& cs = this->Stack.top();
1397
1398 GLint ival;
1399
1400 #ifdef GL_POINT_SIZE
1401 ::glGetFloatv(GL_POINT_SIZE, &cs.PointSize);
1402 #endif
1403 ::glGetFloatv(GL_LINE_WIDTH, &cs.LineWidth);
1404
1405 ::glGetIntegerv(GL_PACK_ALIGNMENT, &cs.PackAlignment);
1406 ::glGetIntegerv(GL_UNPACK_ALIGNMENT, &cs.UnpackAlignment);
1407 ::glGetIntegerv(GL_UNPACK_ROW_LENGTH, &cs.UnpackRowLength);
1408 ::glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &cs.UnpackImageHeight);
1409
1410 ::glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &ival);
1411 cs.StencilMaskBack = static_cast<unsigned int>(ival);
1412 ::glGetIntegerv(GL_STENCIL_WRITEMASK, &ival);
1413 cs.StencilMaskFront = static_cast<unsigned int>(ival);
1414
1415 ::glGetIntegerv(GL_STENCIL_BACK_FAIL, &ival);
1416 cs.StencilOpBack[0] = static_cast<unsigned int>(ival);
1417 ::glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &ival);
1418 cs.StencilOpBack[1] = static_cast<unsigned int>(ival);
1419 ::glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &ival);
1420 cs.StencilOpBack[2] = static_cast<unsigned int>(ival);
1421
1422 ::glGetIntegerv(GL_STENCIL_FAIL, &ival);
1423 cs.StencilOpFront[0] = static_cast<unsigned int>(ival);
1424 ::glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &ival);
1425 cs.StencilOpFront[1] = static_cast<unsigned int>(ival);
1426 ::glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &ival);
1427 cs.StencilOpFront[2] = static_cast<unsigned int>(ival);
1428
1429 ::glGetIntegerv(GL_STENCIL_BACK_FUNC, &ival);
1430 cs.StencilFuncBack[0] = static_cast<unsigned int>(ival);
1431 ::glGetIntegerv(GL_STENCIL_BACK_REF, &ival);
1432 cs.StencilFuncBack[1] = static_cast<unsigned int>(ival);
1433 ::glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &ival);
1434 cs.StencilFuncBack[2] = static_cast<unsigned int>(ival);
1435
1436 ::glGetIntegerv(GL_STENCIL_FUNC, &ival);
1437 cs.StencilFuncFront[0] = static_cast<unsigned int>(ival);
1438 ::glGetIntegerv(GL_STENCIL_REF, &ival);
1439 cs.StencilFuncFront[1] = static_cast<unsigned int>(ival);
1440 ::glGetIntegerv(GL_STENCIL_VALUE_MASK, &ival);
1441 cs.StencilFuncFront[2] = static_cast<unsigned int>(ival);
1442
1443 ::glGetIntegerv(GL_CURRENT_PROGRAM, &cs.BoundProgram);
1444 ::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &cs.BoundVAO);
1445 ::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &cs.BoundArrayBuffer);
1446 ::glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &cs.BoundElementArrayBuffer);
1447 vtkOpenGLRenderUtilities::MarkDebugEvent("Finished Resetting OpenGL State");
1448 }
1449
Push()1450 void vtkOpenGLState::Push()
1451 {
1452 vtkOpenGLRenderUtilities::MarkDebugEvent("Pushing OpenGL State");
1453 this->Stack.push(this->Stack.top());
1454 this->PushFramebufferBindings();
1455 vtkOpenGLRenderUtilities::MarkDebugEvent("Finished Pushing OpenGL State");
1456 }
1457
Pop()1458 void vtkOpenGLState::Pop()
1459 {
1460 vtkOpenGLRenderUtilities::MarkDebugEvent("Popping OpenGL State");
1461 this->Stack.pop();
1462 auto& cs = this->Stack.top();
1463
1464 this->PopFramebufferBindings();
1465
1466 cs.Blend ? ::glEnable(GL_BLEND) : ::glDisable(GL_BLEND);
1467 cs.DepthTest ? ::glEnable(GL_DEPTH_TEST) : ::glDisable(GL_DEPTH_TEST);
1468 #ifdef GL_LINE_SMOOTH
1469 cs.LineSmooth ? ::glEnable(GL_LINE_SMOOTH) : ::glDisable(GL_LINE_SMOOTH);
1470 #endif
1471 cs.StencilTest ? ::glEnable(GL_STENCIL_TEST) : ::glDisable(GL_STENCIL_TEST);
1472 cs.ScissorTest ? ::glEnable(GL_SCISSOR_TEST) : ::glDisable(GL_SCISSOR_TEST);
1473 cs.CullFace ? ::glEnable(GL_CULL_FACE) : ::glDisable(GL_CULL_FACE);
1474 #ifdef GL_TEXTURE_CUBE_MAP_SEAMLESS
1475 cs.CubeMapSeamless ? ::glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS)
1476 : ::glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1477 #endif
1478 #ifdef GL_MULTISAMPLE
1479 cs.MultiSample = glIsEnabled(GL_MULTISAMPLE) == GL_TRUE;
1480 #endif
1481
1482 ::glBlendFuncSeparate(cs.BlendFunc[0], cs.BlendFunc[1], cs.BlendFunc[2], cs.BlendFunc[3]);
1483
1484 ::glClearColor(cs.ClearColor[0], cs.ClearColor[1], cs.ClearColor[2], cs.ClearColor[3]);
1485
1486 ::glColorMask(cs.ColorMask[0], cs.ColorMask[1], cs.ColorMask[2], cs.ColorMask[3]);
1487
1488 ::glDepthFunc(cs.DepthFunc);
1489
1490 #ifdef GL_ES_VERSION_3_0
1491 ::glClearDepthf(cs.ClearDepth);
1492 #else
1493 ::glClearDepth(cs.ClearDepth);
1494 #endif
1495
1496 ::glDepthMask(cs.DepthMask);
1497
1498 #ifndef GL_ES_VERSION_3_0
1499 ::glPointSize(cs.PointSize);
1500 #endif
1501 ::glLineWidth(cs.LineWidth);
1502
1503 ::glPixelStorei(GL_PACK_ALIGNMENT, cs.PackAlignment);
1504 ::glPixelStorei(GL_UNPACK_ALIGNMENT, cs.UnpackAlignment);
1505 ::glPixelStorei(GL_UNPACK_ROW_LENGTH, cs.UnpackRowLength);
1506 ::glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, cs.UnpackImageHeight);
1507
1508 ::glStencilMaskSeparate(GL_FRONT, cs.StencilMaskFront);
1509 ::glStencilMaskSeparate(GL_BACK, cs.StencilMaskBack);
1510 ::glStencilOpSeparate(GL_FRONT, cs.StencilOpFront[0], cs.StencilOpFront[1], cs.StencilOpFront[2]);
1511 ::glStencilOpSeparate(GL_BACK, cs.StencilOpBack[0], cs.StencilOpBack[1], cs.StencilOpBack[2]);
1512 ::glStencilFuncSeparate(GL_FRONT, cs.StencilFuncFront[0],
1513 static_cast<GLint>(cs.StencilFuncFront[1]), cs.StencilFuncFront[2]);
1514 ::glStencilFuncSeparate(GL_BACK, cs.StencilFuncBack[0], static_cast<GLint>(cs.StencilFuncBack[1]),
1515 cs.StencilFuncBack[2]);
1516
1517 ::glViewport(cs.Viewport[0], cs.Viewport[1], cs.Viewport[2], cs.Viewport[3]);
1518
1519 ::glScissor(cs.Scissor[0], cs.Scissor[1], cs.Scissor[2], cs.Scissor[3]);
1520
1521 ::glCullFace(cs.CullFaceMode);
1522
1523 ::glBlendEquationSeparate(cs.BlendEquationValue1, cs.BlendEquationValue2);
1524
1525 if (this->ShaderCache)
1526 {
1527 this->ShaderCache->ReleaseCurrentShader();
1528 }
1529 ::glUseProgram(cs.BoundProgram);
1530
1531 ::glActiveTexture(cs.ActiveTexture);
1532
1533 ::glBindVertexArray(cs.BoundVAO);
1534 ::glBindBuffer(GL_ARRAY_BUFFER, cs.BoundArrayBuffer);
1535 ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cs.BoundElementArrayBuffer);
1536 vtkOpenGLRenderUtilities::MarkDebugEvent("Finished Popping OpenGL State");
1537 }
1538
1539 // make the hardware openglstate match the
1540 // state ivars
Initialize(vtkOpenGLRenderWindow *)1541 void vtkOpenGLState::Initialize(vtkOpenGLRenderWindow*)
1542 {
1543 this->TextureUnitManager->Initialize();
1544 this->InitializeTextureInternalFormats();
1545 auto& cs = this->Stack.top();
1546
1547 cs.Blend ? ::glEnable(GL_BLEND) : ::glDisable(GL_BLEND);
1548 cs.CullFace ? ::glEnable(GL_CULL_FACE) : ::glDisable(GL_CULL_FACE);
1549 cs.DepthTest ? ::glEnable(GL_DEPTH_TEST) : ::glDisable(GL_DEPTH_TEST);
1550 #ifdef GL_LINE_SMOOTH
1551 cs.LineSmooth ? ::glEnable(GL_LINE_SMOOTH) : ::glDisable(GL_LINE_SMOOTH);
1552 #endif
1553 #ifdef GL_MULTISAMPLE
1554 cs.MultiSample = glIsEnabled(GL_MULTISAMPLE) == GL_TRUE;
1555 #endif
1556 cs.StencilTest ? ::glEnable(GL_STENCIL_TEST) : ::glDisable(GL_STENCIL_TEST);
1557 cs.ScissorTest ? ::glEnable(GL_SCISSOR_TEST) : ::glDisable(GL_SCISSOR_TEST);
1558
1559 // initialize blending for transparency
1560 ::glBlendFuncSeparate(cs.BlendFunc[0], cs.BlendFunc[1], cs.BlendFunc[2], cs.BlendFunc[3]);
1561
1562 ::glClearColor(cs.ClearColor[0], cs.ClearColor[1], cs.ClearColor[2], cs.ClearColor[3]);
1563
1564 ::glColorMask(cs.ColorMask[0], cs.ColorMask[1], cs.ColorMask[2], cs.ColorMask[3]);
1565
1566 ::glDepthFunc(cs.DepthFunc);
1567
1568 #ifndef GL_ES_VERSION_3_0
1569 ::glPointSize(cs.PointSize);
1570 #endif
1571 ::glLineWidth(cs.LineWidth);
1572
1573 ::glPixelStorei(GL_PACK_ALIGNMENT, cs.PackAlignment);
1574 ::glPixelStorei(GL_UNPACK_ALIGNMENT, cs.UnpackAlignment);
1575 ::glPixelStorei(GL_UNPACK_ROW_LENGTH, cs.UnpackRowLength);
1576 ::glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, cs.UnpackImageHeight);
1577
1578 ::glStencilMaskSeparate(GL_FRONT, cs.StencilMaskFront);
1579 ::glStencilMaskSeparate(GL_BACK, cs.StencilMaskBack);
1580 ::glStencilOpSeparate(GL_FRONT, cs.StencilOpFront[0], cs.StencilOpFront[1], cs.StencilOpFront[2]);
1581 ::glStencilOpSeparate(GL_BACK, cs.StencilOpBack[0], cs.StencilOpBack[1], cs.StencilOpBack[2]);
1582 ::glStencilFuncSeparate(GL_FRONT, cs.StencilFuncFront[0],
1583 static_cast<GLint>(cs.StencilFuncFront[1]), cs.StencilFuncFront[2]);
1584 ::glStencilFuncSeparate(GL_BACK, cs.StencilFuncBack[0], static_cast<GLint>(cs.StencilFuncBack[1]),
1585 cs.StencilFuncBack[2]);
1586
1587 #ifdef GL_ES_VERSION_3_0
1588 ::glClearDepthf(cs.ClearDepth);
1589 #else
1590 ::glClearDepth(cs.ClearDepth);
1591 #endif
1592
1593 ::glDepthMask(cs.DepthMask);
1594
1595 ::glViewport(cs.Viewport[0], cs.Viewport[1], cs.Viewport[2], cs.Viewport[3]);
1596
1597 ::glScissor(cs.Scissor[0], cs.Scissor[1], cs.Scissor[2], cs.Scissor[3]);
1598
1599 ::glCullFace(cs.CullFaceMode);
1600
1601 ::glBlendEquationSeparate(cs.BlendEquationValue1, cs.BlendEquationValue2);
1602
1603 // strictly query values below here
1604 ::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &this->MaxTextureSize);
1605 ::glGetIntegerv(GL_MAJOR_VERSION, &this->MajorVersion);
1606 ::glGetIntegerv(GL_MINOR_VERSION, &this->MinorVersion);
1607 char const* tmp = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
1608 this->Vendor = tmp ? tmp : std::string();
1609 tmp = reinterpret_cast<char const*>(::glGetString(GL_RENDERER));
1610 this->Renderer = tmp ? tmp : std::string();
1611 tmp = reinterpret_cast<char const*>(::glGetString(GL_VERSION));
1612 this->Version = tmp ? tmp : std::string();
1613
1614 this->ResetFramebufferBindings();
1615 }
1616
GetCurrentDrawFramebufferState(unsigned int & drawBinding,unsigned int & drawBuffer)1617 void vtkOpenGLState::GetCurrentDrawFramebufferState(
1618 unsigned int& drawBinding, unsigned int& drawBuffer)
1619 {
1620 auto& cs = this->Stack.top();
1621 drawBinding = cs.DrawBinding.Binding;
1622 drawBuffer = cs.DrawBinding.DrawBuffers[0];
1623 }
1624
ResetFramebufferBindings()1625 void vtkOpenGLState::ResetFramebufferBindings()
1626 {
1627 auto& cs = this->Stack.top();
1628 ::glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (int*)&cs.DrawBinding.Binding);
1629 #ifdef GL_DRAW_BUFFER
1630 ::glGetIntegerv(GL_DRAW_BUFFER, (int*)&cs.DrawBinding.DrawBuffers[0]);
1631 #endif
1632
1633 ::glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (int*)&cs.ReadBinding.Binding);
1634 ::glGetIntegerv(GL_READ_BUFFER, (int*)&cs.ReadBinding.ReadBuffer);
1635 }
1636
ResetGLClearColorState()1637 void vtkOpenGLState::ResetGLClearColorState()
1638 {
1639 auto& cs = this->Stack.top();
1640 GLfloat fparams[4];
1641 ::glGetFloatv(GL_COLOR_CLEAR_VALUE, fparams);
1642 cs.ClearColor[0] = fparams[0];
1643 cs.ClearColor[1] = fparams[1];
1644 cs.ClearColor[2] = fparams[2];
1645 cs.ClearColor[3] = fparams[3];
1646 }
1647
ResetGLClearDepthState()1648 void vtkOpenGLState::ResetGLClearDepthState()
1649 {
1650 auto& cs = this->Stack.top();
1651 GLfloat fparams;
1652 ::glGetFloatv(GL_DEPTH_CLEAR_VALUE, &fparams);
1653 cs.ClearDepth = fparams;
1654 }
1655
ResetGLDepthFuncState()1656 void vtkOpenGLState::ResetGLDepthFuncState()
1657 {
1658 auto& cs = this->Stack.top();
1659 GLint iparams;
1660 ::glGetIntegerv(GL_DEPTH_FUNC, &iparams);
1661 cs.DepthFunc = static_cast<unsigned int>(iparams);
1662 }
1663
ResetGLDepthMaskState()1664 void vtkOpenGLState::ResetGLDepthMaskState()
1665 {
1666 auto& cs = this->Stack.top();
1667 GLboolean params;
1668 ::glGetBooleanv(GL_DEPTH_WRITEMASK, ¶ms);
1669 cs.DepthMask = params;
1670 }
1671
ResetGLColorMaskState()1672 void vtkOpenGLState::ResetGLColorMaskState()
1673 {
1674 auto& cs = this->Stack.top();
1675 GLboolean params[4];
1676 ::glGetBooleanv(GL_COLOR_WRITEMASK, params);
1677 cs.ColorMask[0] = params[0];
1678 cs.ColorMask[1] = params[1];
1679 cs.ColorMask[2] = params[2];
1680 cs.ColorMask[3] = params[3];
1681 }
1682
ResetGLViewportState()1683 void vtkOpenGLState::ResetGLViewportState()
1684 {
1685 auto& cs = this->Stack.top();
1686 GLint iparams[4];
1687 ::glGetIntegerv(GL_VIEWPORT, iparams);
1688 cs.Viewport[0] = iparams[0];
1689 cs.Viewport[1] = iparams[1];
1690 cs.Viewport[2] = iparams[2];
1691 cs.Viewport[3] = iparams[3];
1692 }
1693
ResetGLScissorState()1694 void vtkOpenGLState::ResetGLScissorState()
1695 {
1696 auto& cs = this->Stack.top();
1697 GLint iparams[4];
1698 ::glGetIntegerv(GL_SCISSOR_BOX, iparams);
1699 cs.Scissor[0] = iparams[0];
1700 cs.Scissor[1] = iparams[1];
1701 cs.Scissor[2] = iparams[2];
1702 cs.Scissor[3] = iparams[3];
1703 }
1704
ResetGLBlendFuncState()1705 void vtkOpenGLState::ResetGLBlendFuncState()
1706 {
1707 auto& cs = this->Stack.top();
1708 GLint iparams;
1709 ::glGetIntegerv(GL_BLEND_SRC_RGB, &iparams);
1710 cs.BlendFunc[0] = static_cast<unsigned int>(iparams);
1711 ::glGetIntegerv(GL_BLEND_SRC_ALPHA, &iparams);
1712 cs.BlendFunc[2] = static_cast<unsigned int>(iparams);
1713 ::glGetIntegerv(GL_BLEND_DST_RGB, &iparams);
1714 cs.BlendFunc[1] = static_cast<unsigned int>(iparams);
1715 ::glGetIntegerv(GL_BLEND_DST_ALPHA, &iparams);
1716 cs.BlendFunc[3] = static_cast<unsigned int>(iparams);
1717 }
1718
ResetGLBlendEquationState()1719 void vtkOpenGLState::ResetGLBlendEquationState()
1720 {
1721 auto& cs = this->Stack.top();
1722 GLint iparams;
1723 ::glGetIntegerv(GL_BLEND_EQUATION_RGB, &iparams);
1724 cs.BlendEquationValue1 = static_cast<unsigned int>(iparams);
1725 ::glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &iparams);
1726 cs.BlendEquationValue2 = static_cast<unsigned int>(iparams);
1727 }
1728
ResetGLCullFaceState()1729 void vtkOpenGLState::ResetGLCullFaceState()
1730 {
1731 auto& cs = this->Stack.top();
1732 GLint iparams;
1733 ::glGetIntegerv(GL_CULL_FACE_MODE, &iparams);
1734 cs.CullFaceMode = static_cast<unsigned int>(iparams);
1735 }
1736
ResetGLActiveTexture()1737 void vtkOpenGLState::ResetGLActiveTexture()
1738 {
1739 auto& cs = this->Stack.top();
1740 GLint iparams;
1741 ::glGetIntegerv(GL_ACTIVE_TEXTURE, &iparams);
1742 cs.ActiveTexture = static_cast<unsigned int>(iparams);
1743 }
1744
vtkglClear(GLbitfield val)1745 void vtkOpenGLState::vtkglClear(GLbitfield val)
1746 {
1747 ::glClear(val);
1748 }
1749
vtkglBlitFramebuffer(int srcX0,int srcY0,int srcX1,int srcY1,int dstX0,int dstY0,int dstX1,int dstY1,unsigned int mask,unsigned int filter)1750 void vtkOpenGLState::vtkglBlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0,
1751 int dstY0, int dstX1, int dstY1, unsigned int mask, unsigned int filter)
1752 {
1753 // ON APPLE MACOS you must turn off scissor test for DEPTH blits to work
1754 vtkOpenGLState::ScopedglEnableDisable stsaver(this, GL_SCISSOR_TEST);
1755 this->vtkglDisable(GL_SCISSOR_TEST);
1756
1757 ::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1758 }
1759
1760 //------------------------------------------------------------------------------
1761 // Description:
1762 // Returns its texture unit manager object.
GetTextureUnitManager()1763 vtkTextureUnitManager* vtkOpenGLState::GetTextureUnitManager()
1764 {
1765 return this->TextureUnitManager;
1766 }
1767
SetTextureUnitManager(vtkTextureUnitManager * tum)1768 void vtkOpenGLState::SetTextureUnitManager(vtkTextureUnitManager* tum)
1769 {
1770 if (this->TextureUnitManager == tum)
1771 {
1772 return;
1773 }
1774 if (tum)
1775 {
1776 tum->Register(nullptr);
1777 }
1778 if (this->TextureUnitManager)
1779 {
1780 this->TextureUnitManager->Delete();
1781 }
1782 this->TextureUnitManager = tum;
1783 }
1784
ActivateTexture(vtkTextureObject * texture)1785 void vtkOpenGLState::ActivateTexture(vtkTextureObject* texture)
1786 {
1787 // Only add if it isn't already there
1788 typedef std::map<const vtkTextureObject*, int>::const_iterator TRIter;
1789 TRIter found = this->TextureResourceIds.find(texture);
1790 if (found == this->TextureResourceIds.end())
1791 {
1792 int activeUnit = this->GetTextureUnitManager()->Allocate();
1793 if (activeUnit < 0)
1794 {
1795 vtkGenericWarningMacro("Hardware does not support the number of textures defined.");
1796 return;
1797 }
1798 this->TextureResourceIds.insert(std::make_pair(texture, activeUnit));
1799 this->vtkglActiveTexture(GL_TEXTURE0 + activeUnit);
1800 }
1801 else
1802 {
1803 this->vtkglActiveTexture(GL_TEXTURE0 + found->second);
1804 }
1805 }
1806
DeactivateTexture(vtkTextureObject * texture)1807 void vtkOpenGLState::DeactivateTexture(vtkTextureObject* texture)
1808 {
1809 // Only deactivate if it isn't already there
1810 typedef std::map<const vtkTextureObject*, int>::iterator TRIter;
1811 TRIter found = this->TextureResourceIds.find(texture);
1812 if (found != this->TextureResourceIds.end())
1813 {
1814 this->GetTextureUnitManager()->Free(found->second);
1815 this->TextureResourceIds.erase(found);
1816 }
1817 }
1818
GetTextureUnitForTexture(vtkTextureObject * texture)1819 int vtkOpenGLState::GetTextureUnitForTexture(vtkTextureObject* texture)
1820 {
1821 // Only deactivate if it isn't already there
1822 typedef std::map<const vtkTextureObject*, int>::const_iterator TRIter;
1823 TRIter found = this->TextureResourceIds.find(texture);
1824 if (found != this->TextureResourceIds.end())
1825 {
1826 return found->second;
1827 }
1828
1829 return -1;
1830 }
1831
VerifyNoActiveTextures()1832 void vtkOpenGLState::VerifyNoActiveTextures()
1833 {
1834 if (!this->TextureResourceIds.empty())
1835 {
1836 vtkGenericWarningMacro("There are still active textures when there should not be.");
1837 typedef std::map<const vtkTextureObject*, int>::const_iterator TRIter;
1838 TRIter found = this->TextureResourceIds.begin();
1839 for (; found != this->TextureResourceIds.end(); ++found)
1840 {
1841 vtkGenericWarningMacro(
1842 "Leaked for texture object: " << const_cast<vtkTextureObject*>(found->first));
1843 }
1844 }
1845 }
1846
1847 vtkStandardNewMacro(vtkOpenGLState);
1848
PrintSelf(ostream & os,vtkIndent indent)1849 void vtkOpenGLState::PrintSelf(ostream& os, vtkIndent indent)
1850 {
1851 this->Superclass::PrintSelf(os, indent);
1852 os << indent << "MajorVersion: " << this->MajorVersion << endl;
1853 os << indent << "MinorVersion: " << this->MinorVersion << endl;
1854 os << indent << "MaxTextureSize: " << this->MaxTextureSize << endl;
1855 os << indent << "Vendor: " << this->Vendor << endl;
1856 os << indent << "Renderer: " << this->Renderer << endl;
1857 os << indent << "Version: " << this->Version << endl;
1858 }
1859
1860 vtkCxxSetObjectMacro(vtkOpenGLState, VBOCache, vtkOpenGLVertexBufferObjectCache);
1861
1862 // initialize all state values. This is important so that in
1863 // ::Initialize we can just set the state to the current
1864 // values (knowing that they are set). The reason we want
1865 // Initialize to set to the current values is to reduce
1866 // OpenGL churn in cases where applications call Initialize
1867 // often without really changing many of the values. For example
1868 //
1869 // viewport(0,0,100,100);
1870 // Initialize(0,0,1,1); // using hardcoded initialization
1871 // viewport(0,0,100,100);
1872 //
1873 // versus
1874 //
1875 // viewport(0,0,100,100);
1876 // Initialize(0,0,100,100); // using last value
1877 // viewport(0,0,100,100); // cache will skip this line
1878 //
1879 // Using current values avoids extra state changes when
1880 // not required.
1881 //
vtkOpenGLState()1882 vtkOpenGLState::vtkOpenGLState()
1883 {
1884 this->ShaderCache = vtkOpenGLShaderCache::New();
1885 this->VBOCache = vtkOpenGLVertexBufferObjectCache::New();
1886
1887 this->TextureUnitManager = vtkTextureUnitManager::New();
1888
1889 this->Stack.push(GLState());
1890
1891 auto& cs = this->Stack.top();
1892
1893 cs.Blend = true;
1894 cs.DepthTest = true;
1895 cs.StencilTest = false;
1896 cs.ScissorTest = true;
1897 cs.CullFace = false;
1898 cs.CubeMapSeamless = false;
1899 cs.LineSmooth = false;
1900 cs.MultiSample = false;
1901
1902 cs.LineWidth = 1.0;
1903 cs.PointSize = 1.0;
1904
1905 cs.StencilMaskFront = 0xFF;
1906 cs.StencilMaskBack = 0xFF;
1907
1908 cs.StencilOpFront[0] = GL_KEEP;
1909 cs.StencilOpFront[1] = GL_KEEP;
1910 cs.StencilOpFront[2] = GL_KEEP;
1911 cs.StencilOpBack[0] = GL_KEEP;
1912 cs.StencilOpBack[1] = GL_KEEP;
1913 cs.StencilOpBack[2] = GL_KEEP;
1914
1915 cs.StencilFuncFront[0] = GL_ALWAYS;
1916 cs.StencilFuncFront[1] = 0;
1917 cs.StencilFuncFront[2] = 0xFF;
1918 cs.StencilFuncBack[0] = GL_ALWAYS;
1919 cs.StencilFuncBack[1] = 0;
1920 cs.StencilFuncBack[2] = 0xFF;
1921
1922 cs.PackAlignment = 1;
1923 cs.UnpackAlignment = 1;
1924 cs.UnpackRowLength = 0;
1925 cs.UnpackImageHeight = 0;
1926
1927 // initialize blending for transparency
1928 cs.BlendFunc[0] = GL_SRC_ALPHA;
1929 cs.BlendFunc[1] = GL_ONE_MINUS_SRC_ALPHA;
1930 cs.BlendFunc[2] = GL_ONE;
1931 cs.BlendFunc[3] = GL_ONE_MINUS_SRC_ALPHA;
1932
1933 cs.ClearColor[0] = 0.0;
1934 cs.ClearColor[1] = 0.0;
1935 cs.ClearColor[2] = 0.0;
1936 cs.ClearColor[3] = 0.0;
1937
1938 cs.ColorMask[0] = GL_TRUE;
1939 cs.ColorMask[1] = GL_TRUE;
1940 cs.ColorMask[2] = GL_TRUE;
1941 cs.ColorMask[3] = GL_TRUE;
1942
1943 cs.DepthFunc = GL_LEQUAL;
1944
1945 cs.ClearDepth = 1.0;
1946
1947 cs.DepthMask = GL_TRUE;
1948
1949 cs.Viewport[0] = 0;
1950 cs.Viewport[1] = 0;
1951 cs.Viewport[2] = 1;
1952 cs.Viewport[3] = 1;
1953
1954 cs.Scissor[0] = 0;
1955 cs.Scissor[1] = 0;
1956 cs.Scissor[2] = 1;
1957 cs.Scissor[3] = 1;
1958
1959 cs.CullFaceMode = GL_BACK;
1960 cs.ActiveTexture = GL_TEXTURE0;
1961
1962 cs.BlendEquationValue1 = GL_FUNC_ADD;
1963 cs.BlendEquationValue2 = GL_FUNC_ADD;
1964
1965 cs.DrawBinding.Binding = 0;
1966 cs.ReadBinding.Binding = 0;
1967 cs.DrawBinding.DrawBuffers[0] = GL_BACK_LEFT;
1968 for (int i = 1; i < 10; ++i)
1969 {
1970 cs.DrawBinding.DrawBuffers[i] = GL_NONE;
1971 }
1972 cs.ReadBinding.ReadBuffer = GL_BACK_LEFT;
1973 }
1974
~vtkOpenGLState()1975 vtkOpenGLState::~vtkOpenGLState()
1976 {
1977 this->TextureResourceIds.clear();
1978 this->SetTextureUnitManager(nullptr);
1979 this->VBOCache->Delete();
1980 this->ShaderCache->Delete();
1981 }
1982
PushDrawFramebufferBinding()1983 void vtkOpenGLState::PushDrawFramebufferBinding()
1984 {
1985 auto& cs = this->Stack.top();
1986 this->DrawBindings.push_back(cs.DrawBinding);
1987 }
1988
PushReadFramebufferBinding()1989 void vtkOpenGLState::PushReadFramebufferBinding()
1990 {
1991 auto& cs = this->Stack.top();
1992 this->ReadBindings.push_back(cs.ReadBinding);
1993 }
1994
PopDrawFramebufferBinding()1995 void vtkOpenGLState::PopDrawFramebufferBinding()
1996 {
1997 if (!this->DrawBindings.empty())
1998 {
1999 auto& cs = this->Stack.top();
2000 BufferBindingState& bbs = this->DrawBindings.back();
2001 ::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bbs.GetBinding());
2002 cs.DrawBinding = bbs;
2003 this->DrawBindings.pop_back();
2004 }
2005 else
2006 {
2007 vtkGenericWarningMacro("Attempt to pop framebuffer beyond beginning of the stack.");
2008 abort();
2009 }
2010 }
2011
PopReadFramebufferBinding()2012 void vtkOpenGLState::PopReadFramebufferBinding()
2013 {
2014 if (!this->ReadBindings.empty())
2015 {
2016 auto& cs = this->Stack.top();
2017 BufferBindingState& bbs = this->ReadBindings.back();
2018 ::glBindFramebuffer(GL_READ_FRAMEBUFFER, bbs.GetBinding());
2019 cs.ReadBinding = bbs;
2020 this->ReadBindings.pop_back();
2021 }
2022 else
2023 {
2024 vtkGenericWarningMacro("Attempt to pop framebuffer beyond beginning of the stack.");
2025 abort();
2026 }
2027 }
2028
GetDefaultTextureInternalFormat(int vtktype,int numComponents,bool needInt,bool needFloat,bool needSRGB)2029 int vtkOpenGLState::GetDefaultTextureInternalFormat(
2030 int vtktype, int numComponents, bool needInt, bool needFloat, bool needSRGB)
2031 {
2032 // 0 = none
2033 // 1 = float
2034 // 2 = int
2035 if (vtktype >= VTK_UNICODE_STRING)
2036 {
2037 return 0;
2038 }
2039 if (needInt)
2040 {
2041 return this->TextureInternalFormats[vtktype][2][numComponents];
2042 }
2043 if (needFloat)
2044 {
2045 return this->TextureInternalFormats[vtktype][1][numComponents];
2046 }
2047 int result = this->TextureInternalFormats[vtktype][0][numComponents];
2048 if (needSRGB)
2049 {
2050 switch (result)
2051 {
2052 #ifdef GL_ES_VERSION_3_0
2053 case GL_RGB:
2054 result = GL_SRGB8;
2055 break;
2056 case GL_RGBA:
2057 result = GL_SRGB8_ALPHA8;
2058 break;
2059 #else
2060 case GL_RGB:
2061 result = GL_SRGB;
2062 break;
2063 case GL_RGBA:
2064 result = GL_SRGB_ALPHA;
2065 break;
2066 #endif
2067 case GL_RGB8:
2068 result = GL_SRGB8;
2069 break;
2070 case GL_RGBA8:
2071 result = GL_SRGB8_ALPHA8;
2072 break;
2073 default:
2074 break;
2075 }
2076 }
2077 return result;
2078 }
2079
InitializeTextureInternalFormats()2080 void vtkOpenGLState::InitializeTextureInternalFormats()
2081 {
2082 // 0 = none
2083 // 1 = float
2084 // 2 = int
2085
2086 // initialize to zero
2087 for (int dtype = 0; dtype < VTK_UNICODE_STRING; dtype++)
2088 {
2089 for (int ctype = 0; ctype < 3; ctype++)
2090 {
2091 for (int comp = 0; comp <= 4; comp++)
2092 {
2093 this->TextureInternalFormats[dtype][ctype][comp] = 0;
2094 }
2095 }
2096 }
2097
2098 this->TextureInternalFormats[VTK_VOID][0][1] = GL_DEPTH_COMPONENT;
2099
2100 #ifdef GL_R8
2101 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][1] = GL_R8;
2102 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][2] = GL_RG8;
2103 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][3] = GL_RGB8;
2104 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][4] = GL_RGBA8;
2105 #else
2106 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][1] = GL_LUMINANCE;
2107 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][2] = GL_LUMINANCE_ALPHA;
2108 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][3] = GL_RGB;
2109 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][0][4] = GL_RGBA;
2110 #endif
2111
2112 #ifdef GL_R16
2113 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][0][1] = GL_R16;
2114 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][0][2] = GL_RG16;
2115 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][0][3] = GL_RGB16;
2116 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][0][4] = GL_RGBA16;
2117 #endif
2118
2119 #ifdef GL_R8_SNORM
2120 this->TextureInternalFormats[VTK_SIGNED_CHAR][0][1] = GL_R8_SNORM;
2121 this->TextureInternalFormats[VTK_SIGNED_CHAR][0][2] = GL_RG8_SNORM;
2122 this->TextureInternalFormats[VTK_SIGNED_CHAR][0][3] = GL_RGB8_SNORM;
2123 this->TextureInternalFormats[VTK_SIGNED_CHAR][0][4] = GL_RGBA8_SNORM;
2124 #endif
2125
2126 #ifdef GL_R16_SNORM
2127 this->TextureInternalFormats[VTK_SHORT][0][1] = GL_R16_SNORM;
2128 this->TextureInternalFormats[VTK_SHORT][0][2] = GL_RG16_SNORM;
2129 this->TextureInternalFormats[VTK_SHORT][0][3] = GL_RGB16_SNORM;
2130 this->TextureInternalFormats[VTK_SHORT][0][4] = GL_RGBA16_SNORM;
2131 #endif
2132
2133 #ifdef GL_R8I
2134 this->TextureInternalFormats[VTK_SIGNED_CHAR][2][1] = GL_R8I;
2135 this->TextureInternalFormats[VTK_SIGNED_CHAR][2][2] = GL_RG8I;
2136 this->TextureInternalFormats[VTK_SIGNED_CHAR][2][3] = GL_RGB8I;
2137 this->TextureInternalFormats[VTK_SIGNED_CHAR][2][4] = GL_RGBA8I;
2138 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][2][1] = GL_R8UI;
2139 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][2][2] = GL_RG8UI;
2140 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][2][3] = GL_RGB8UI;
2141 this->TextureInternalFormats[VTK_UNSIGNED_CHAR][2][4] = GL_RGBA8UI;
2142
2143 this->TextureInternalFormats[VTK_SHORT][2][1] = GL_R16I;
2144 this->TextureInternalFormats[VTK_SHORT][2][2] = GL_RG16I;
2145 this->TextureInternalFormats[VTK_SHORT][2][3] = GL_RGB16I;
2146 this->TextureInternalFormats[VTK_SHORT][2][4] = GL_RGBA16I;
2147 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][2][1] = GL_R16UI;
2148 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][2][2] = GL_RG16UI;
2149 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][2][3] = GL_RGB16UI;
2150 this->TextureInternalFormats[VTK_UNSIGNED_SHORT][2][4] = GL_RGBA16UI;
2151
2152 this->TextureInternalFormats[VTK_INT][2][1] = GL_R32I;
2153 this->TextureInternalFormats[VTK_INT][2][2] = GL_RG32I;
2154 this->TextureInternalFormats[VTK_INT][2][3] = GL_RGB32I;
2155 this->TextureInternalFormats[VTK_INT][2][4] = GL_RGBA32I;
2156 this->TextureInternalFormats[VTK_UNSIGNED_INT][2][1] = GL_R32UI;
2157 this->TextureInternalFormats[VTK_UNSIGNED_INT][2][2] = GL_RG32UI;
2158 this->TextureInternalFormats[VTK_UNSIGNED_INT][2][3] = GL_RGB32UI;
2159 this->TextureInternalFormats[VTK_UNSIGNED_INT][2][4] = GL_RGBA32UI;
2160 #endif
2161
2162 // on mesa we may not have float textures even though we think we do
2163 // this is due to Mesa being impacted by a patent issue with SGI
2164 // that is due to expire in the US in summer 2018
2165 #ifndef GL_ES_VERSION_3_0
2166 const char* glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
2167 if (glVersion && strstr(glVersion, "Mesa") != nullptr && !GLEW_ARB_texture_float)
2168 {
2169 // mesa without float support cannot even use
2170 // uchar textures with underlying float data
2171 // so pretty much anything with float data
2172 // is out of luck so return
2173 return;
2174 }
2175 #endif
2176
2177 #ifdef GL_R32F
2178 this->TextureInternalFormats[VTK_FLOAT][1][1] = GL_R32F;
2179 this->TextureInternalFormats[VTK_FLOAT][1][2] = GL_RG32F;
2180 this->TextureInternalFormats[VTK_FLOAT][1][3] = GL_RGB32F;
2181 this->TextureInternalFormats[VTK_FLOAT][1][4] = GL_RGBA32F;
2182
2183 this->TextureInternalFormats[VTK_SHORT][1][1] = GL_R32F;
2184 this->TextureInternalFormats[VTK_SHORT][1][2] = GL_RG32F;
2185 this->TextureInternalFormats[VTK_SHORT][1][3] = GL_RGB32F;
2186 this->TextureInternalFormats[VTK_SHORT][1][4] = GL_RGBA32F;
2187 #endif
2188 }
2189