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, &params);
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, &params);
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