Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
OpenGLContext.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
34 #include <vlGraphics/OpenGL.hpp>
36 #include <vlGraphics/Shader.hpp>
37 #include <vlGraphics/GLSL.hpp>
38 #include <vlGraphics/Light.hpp>
39 #include <vlGraphics/ClipPlane.hpp>
40 #include <vlCore/Log.hpp>
41 #include <vlCore/Say.hpp>
42 #include <algorithm>
43 #include <sstream>
45 
46 using namespace vl;
47 
48 //-----------------------------------------------------------------------------
49 // UIEventListener
50 //-----------------------------------------------------------------------------
51 OpenGLContext* UIEventListener::openglContext() { return mOpenGLContext; }
52 //-----------------------------------------------------------------------------
53 // OpenGLContext
54 //-----------------------------------------------------------------------------
56 {
57  VL_DEBUG_SET_OBJECT_NAME()
58  mLeftFramebuffer = new Framebuffer(this, w, h, RDB_BACK_LEFT, RDB_BACK_LEFT);
59  mRightFramebuffer = new Framebuffer(this, w, h, RDB_BACK_RIGHT, RDB_BACK_RIGHT);
60 
61  mDefaultVAO = 0;
62 
63  // set to unknown texture target
64  memset( mTexUnitBinding, 0, sizeof(mTexUnitBinding) );
65 
66  mCurrentEnableSet = new NaryQuickMap<EEnable, EEnable, EN_EnableCount>;
68 
71 
72  mIsInitialized = false;
73  mHasDoubleBuffer = false;
74  mVertexAttribCount = 0;
75  mTextureImageUnitCount = 0;
76  mTextureCoordCount = 0;
77  mCurVAS = NULL;
78  mGLSLUpdated = true;
79 
80  mNormal = fvec3(0,1,0);
81  mColor = fvec4(1,1,1,1);
82  mSecondaryColor = fvec3(1,1,1);
83 
84  // --- GUI ---
85 
86  mMouseVisible = true;
87  mContinuousUpdate = true;
88  mIgnoreNextMouseMoveEvent = false;
89  mFullscreen = false;
90 }
91 //-----------------------------------------------------------------------------
93 {
94  if ( mLeftFramebuffer || mRightFramebuffer || mFramebufferObject.size() || mEventListeners.size() )
95  {
96  Log::warning("~OpenGLContext() called before dispatchDestroyEvent(), your application will likely crash.\n");
97  VL_TRAP();
98  }
99 }
100 //-----------------------------------------------------------------------------
102 {
103  makeCurrent();
104  mFramebufferObject.push_back(new FramebufferObject(this, width, height, draw_buffer, read_buffer));
105  mFramebufferObject.back()->createFBO();
106  return mFramebufferObject.back();
107 }
108 //-----------------------------------------------------------------------------
110 {
111  makeCurrent();
112  for(unsigned i=0; i<mFramebufferObject.size(); ++i)
113  {
114  if (mFramebufferObject[i] == fbort)
115  {
116  mFramebufferObject[i]->deleteFBO();
117  mFramebufferObject[i]->mOpenGLContext = NULL;
118  mFramebufferObject.erase(mFramebufferObject.begin()+i);
119  return;
120  }
121  }
122 }
123 //-----------------------------------------------------------------------------
125 {
126  if ( mIsInitialized ) {
127  mIsInitialized = false;
128  makeCurrent();
129  destroyAllFramebufferObjects();
130  mLeftFramebuffer->mOpenGLContext = NULL;
131  mRightFramebuffer->mOpenGLContext = NULL;
132  mLeftFramebuffer = NULL;
133  mRightFramebuffer = NULL;
134  for( int i=0; i<RS_RenderStateCount; ++i )
135  {
136  mDefaultRenderStates[i].mRS = NULL;
137  }
138  mCurrentEnableSet = NULL;
139  mNewEnableSet = NULL;
140  mCurrentRenderStateSet = NULL;
141  mNewRenderStateSet = NULL;
142  mGLSLProgram = NULL;
143  for( int i=0; i<VL_MAX_TEXTURE_IMAGE_UNITS; ++i )
144  {
145  mTexUnitBinding[ i ] = vl::TD_TEXTURE_UNKNOWN;
146  }
147  }
148 }
149 //-----------------------------------------------------------------------------
151 {
152  makeCurrent();
153  for(unsigned i=0; i<mFramebufferObject.size(); ++i)
154  {
155  mFramebufferObject[i]->deleteFBO();
156  mFramebufferObject[i]->mOpenGLContext = NULL;
157  }
158  mFramebufferObject.clear();
159 }
160 //-----------------------------------------------------------------------------
162 {
163  VL_CHECK( el );
164  VL_CHECK( el->mOpenGLContext == NULL );
165  if (el->mOpenGLContext == NULL)
166  {
167  mEventListeners.push_back(el);
168  el->mOpenGLContext = this;
169  el->addedListenerEvent(this);
170  if (isInitialized())
171  el->initEvent();
172  }
173 }
174 //-----------------------------------------------------------------------------
176 {
177  VL_CHECK( el );
178  VL_CHECK( el->mOpenGLContext == this || el->mOpenGLContext == NULL );
179  if (el->mOpenGLContext == this)
180  {
181  std::vector< ref<UIEventListener> >::iterator pos = std::find(mEventListeners.begin(), mEventListeners.end(), el);
182  if( pos != mEventListeners.end() )
183  {
184  mEventListeners.erase( pos );
185  // any operation here is safe, even adding or removing listeners.
186  el->removedListenerEvent(this);
187  el->mOpenGLContext = NULL;
188  }
189  }
190 }
191 //-----------------------------------------------------------------------------
193 {
194  // iterate on a temp vector so that any operations inside removedListenerEvent() is safe,
195  // even adding or removing listeners.
196  std::vector< ref<UIEventListener> > temp = mEventListeners;
197  mEventListeners.clear();
198  for(size_t i=0; i<temp.size(); ++i)
199  {
200  VL_CHECK( temp[i]->mOpenGLContext == this );
201  temp[i]->removedListenerEvent(this);
202  temp[i]->mOpenGLContext = NULL;
203  }
204 }
205 //-----------------------------------------------------------------------------
207 {
208 #if defined(VL_OPENGL) && defined(VL_PLATFORM_WINDOWS)
209  makeCurrent();
210  if (Has_GL_EXT_swap_control)
211  wglSwapIntervalEXT(enable?1:0);
212 #else
213  // Mac and Linux?
214  /*
215  makeCurrent();
216  if (Has_GLX_EXT_swap_control)
217  glXSwapIntervalEXT(enable);
218  */
219 #endif
220 }
221 //-----------------------------------------------------------------------------
223 {
224 #if defined(VL_OPENGL) && defined(VL_PLATFORM_WINDOWS)
225  if (Has_GL_EXT_swap_control)
226  return wglGetSwapIntervalEXT() != 0;
227  else
228  return false;
229 #else
230  return false;
231 #endif
232 }
233 //-----------------------------------------------------------------------------
235 {
236  mIsInitialized = false;
237 
238  makeCurrent();
239 
240  // init OpenGL extensions
241  if (!initializeOpenGL())
242  {
243  Log::error("Error initializing OpenGL!\n");
244  VL_TRAP()
245  return false;
246  }
247 
248  mExtensions = getOpenGLExtensions();
249 
250  if (log)
251  logOpenGLInfo();
252 
253  VL_CHECK_OGL();
254 
255  // Find max number of texture units, see http://www.opengl.org/sdk/docs/man/xhtml/glActiveTexture.xml
256  mTextureImageUnitCount = mTextureCoordCount = 1;
257  if (Has_GL_ARB_multitexture||Has_GL_Version_1_3||Has_GLES_Version_1_1) // for GL < 2.x
258  {
259  int max_tmp = 0;
260  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
261  mTextureCoordCount = mTextureImageUnitCount = max_tmp > mTextureImageUnitCount ? max_tmp : mTextureImageUnitCount;
262  }
263  if (Has_GL_Version_2_0) // for GL == 2.x
264  {
265  int max_tmp = 0;
266  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
267  mTextureCoordCount = mTextureImageUnitCount = max_tmp > mTextureImageUnitCount ? max_tmp : mTextureImageUnitCount;
268  }
269  if (Has_GLSL) // for GL >= 2.0
270  {
271  int max_tmp = 0;
272  glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_tmp); VL_CHECK_OGL();
273  mTextureImageUnitCount = max_tmp > mTextureImageUnitCount ? max_tmp : mTextureImageUnitCount;
274  }
275  mTextureImageUnitCount = mTextureImageUnitCount < VL_MAX_TEXTURE_IMAGE_UNITS ? mTextureImageUnitCount : VL_MAX_TEXTURE_IMAGE_UNITS;
276  mTextureCoordCount = mTextureCoordCount < VL_MAX_LEGACY_TEXTURE_UNITS ? mTextureCoordCount : VL_MAX_LEGACY_TEXTURE_UNITS;
277 
278  // find max number of vertex attributes
279  mVertexAttribCount = 0;
280  if(Has_GLSL)
281  glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mVertexAttribCount);
282  mVertexAttribCount = mVertexAttribCount < VA_MaxAttribCount ? mVertexAttribCount : VA_MaxAttribCount;
283 
284  // default VAO needed for OpenGL Core profiles
285  if ( Is_OpenGL_Core_Profile && glGenVertexArrays && glBindVertexArray ) {
286  glGenVertexArrays( 1, &mDefaultVAO ); VL_CHECK_OGL();
287  glBindVertexArray( mDefaultVAO ); VL_CHECK_OGL();
288  }
289 
290  VL_CHECK_OGL();
291 
292 #if defined(VL_OPENGL)
293  // test for double buffer availability
294  glDrawBuffer(GL_BACK);
295  if ( glGetError() )
296  mHasDoubleBuffer = false;
297  else
298  mHasDoubleBuffer = true;
299 #else
300  mHasDoubleBuffer = true;
301 #endif
302 
303  setupDefaultRenderStates();
304 
305  return mIsInitialized = true;
306 }
307 //-----------------------------------------------------------------------------
308 bool OpenGLContext::isExtensionSupported(const char* ext_name)
309 {
310  makeCurrent();
311  size_t len = strlen(ext_name);
312  const char* ext = mExtensions.c_str();
313  const char* ext_end = ext + strlen(ext);
314 
315  for( const char* pos = strstr(ext,ext_name); pos && pos < ext_end; pos = strstr(pos,ext_name) )
316  {
317  if (pos[len] == ' ' || pos[len] == 0)
318  return true;
319  else
320  pos += len;
321  }
322 
323  return false;
324 }
325 //-----------------------------------------------------------------------------
326 void* OpenGLContext::getProcAddress(const char* function_name)
327 {
328  makeCurrent();
329  return getGLProcAddress(function_name);
330 }
331 //-----------------------------------------------------------------------------
333 {
334  makeCurrent();
335 
336  Log::debug(" --- OpenGL Info ---\n");
337  Log::debug( Say("OpenGL version: %s\n") << glGetString(GL_VERSION) );
338  Log::debug( Say("OpenGL vendor: %s\n") << glGetString(GL_VENDOR) );
339  Log::debug( Say("OpenGL renderer: %s\n") << glGetString(GL_RENDERER) );
340  Log::debug( Say("OpenGL profile: %s\n") << (Has_Fixed_Function_Pipeline ? "Compatible" : "Core") );
341 
342  if (Has_GLSL)
343  Log::debug( Say("GLSL version: %s\n") << glGetString(GL_SHADING_LANGUAGE_VERSION) );
344 
345  int max_val = 0;
346  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_val);
347  Log::debug( Say("Max texture size: %n\n")<<max_val);
348 
349  max_val = 1;
350  if (Has_GL_ARB_multitexture||Has_GL_Version_1_3||Has_GLES_Version_1_1)
351  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_val); // deprecated enum
352  Log::debug( Say("Texture units (legacy): %n\n") << max_val);
353 
354  max_val = 0;
355  if (Has_GL_Version_2_0)
356  {
357  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_val); // deprecated enum
358  Log::debug( Say("Texture units (client): %n\n") << max_val);
359  }
360  if (Has_GLSL)
361  {
362  int tmp = 0;
363  glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &tmp);
364  // max between GL_MAX_TEXTURE_COORDS and GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
365  max_val = tmp > max_val ? tmp : max_val;
366  Log::debug( Say("Texture units (combined): %n\n") << max_val);
367  }
368 
369  max_val = 0;
370  if (Has_GLSL)
371  {
372  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_val);
373  Log::debug( Say("Texture units (fragment shader): %n\n") << max_val);
374  }
375 
376  max_val = 0;
377  if (Has_GL_EXT_texture_filter_anisotropic)
378  glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_val);
379  Log::debug( Say("Anisotropic texture filter: %s, ") << (Has_GL_EXT_texture_filter_anisotropic? "YES" : "NO") );
380  Has_GL_EXT_texture_filter_anisotropic ? Log::debug( Say("%nX\n") << max_val) : Log::debug("\n");
381  Log::debug( Say("S3 Texture Compression: %s\n") << (Has_GL_EXT_texture_compression_s3tc? "YES" : "NO") );
382  Log::debug( Say("Vertex Buffer Object: %s\n") << (Has_BufferObject? "YES" : "NO"));
383  Log::debug( Say("Pixel Buffer Object: %s\n") << (Has_PBO ? "YES" : "NO"));
384  Log::debug( Say("Framebuffer Object: %s\n") << (Has_FBO? "YES" : "NO"));
385 
386  max_val = 0;
387  if(Has_GLSL)
388  {
389  glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_val); VL_CHECK_OGL();
390  Log::debug( Say("Max vertex attributes: %n\n")<<max_val);
391  }
392 
393  VL_CHECK_OGL();
394 
395  max_val = 0;
396  if(Has_GLSL)
397  {
398  // - opengl 3.2 seem to deprecate both GL_MAX_VARYING_COMPONENTS and GL_MAX_VARYING_FLOATS
399  // but does not support explicitly GL_MAX_VARYING_VECTORS, leving the issue ambiguous.
400  // - my GTX 460 in opengl 3.2 core allows GL_MAX_VARYING_VECTORS
401  // - a user reported that a Quadro FX GL 3.2 compatibility did not support GL_MAX_VARYING_VECTORS
402  // - ergo we don't check if we are in GL 3.x non-compatible mode
404  {
405  glGetIntegerv(GL_MAX_VARYING_VECTORS, &max_val); VL_CHECK_OGL();
406  }
407  else
408  if (Has_GL_Version_2_0)
409  {
410  glGetIntegerv(GL_MAX_VARYING_FLOATS, &max_val); VL_CHECK_OGL();
411  max_val /= 4;
412  }
413  Log::debug( Say("Max varying vectors: %n\n")<<max_val);
414  }
415 
416  max_val = 0;
417  if(Has_GLSL)
418  {
420  {
421  glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &max_val); VL_CHECK_OGL();
422  }
423  else
424  {
425  glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max_val); VL_CHECK_OGL();
426  max_val /= 4;
427  }
428 
429  Log::debug( Say("Max fragment uniform vectors: %n\n")<<max_val);
430  }
431 
432  max_val = 0;
433  if(Has_GLSL)
434  {
436  {
437  glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &max_val); VL_CHECK_OGL();
438  }
439  else
440  {
441  glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max_val); VL_CHECK_OGL();
442  max_val /= 4;
443  }
444 
445  Log::debug( Say("Max vertex uniform vectors: %n\n")<<max_val);
446  }
447 
448  max_val = 0;
450  {
451  glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_val); VL_CHECK_OGL();
452  Log::debug( Say("Max elements vertices: %n\n") << max_val );
453  }
454 
455  max_val = 0;
457  {
458  glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &max_val ); VL_CHECK_OGL();
459  Log::debug( Say("Max elements indices: %n\n") << max_val );
460  }
461 
463  {
464  max_val = 0;
465  glGetIntegerv(GL_MAX_CLIP_PLANES, &max_val ); VL_CHECK_OGL();
466  Log::debug( Say("Max clipping planes: %n\n") << max_val );
467  }
468  else
470  {
471  max_val = 0;
472  glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max_val ); VL_CHECK_OGL();
473  Log::debug( Say("Max clip distances: %n\n") << max_val );
474  }
475 
476  // --- log supported extensions on two columns ---
477 
478  Log::debug("\n --- OpenGL Extensions --- \n");
479 
480  std::stringstream sstream;
481  sstream << extensions();
482  std::string ext, line;
483  for( int i=0; !sstream.eof(); ++i )
484  {
485  sstream >> ext;
486  if (sstream.eof())
487  break;
488 
489  if (i && i % 2)
490  {
491  line.resize(40,' ');
492  line += ext;
493  Log::debug( Say("%s\n") << line );
494  line.clear();
495  }
496  else
497  line = ext;
498  }
499  if (line.length())
500  Log::debug( Say("%s\n") << line );
501  Log::debug("\n");
502 
503  VL_CHECK_OGL();
504 }
505 //------------------------------------------------------------------------------
506 void OpenGLContext::applyEnables( const EnableSet* new_enables )
507 {
508  VL_CHECK_OGL()
509 
510  mNewEnableSet->clear();
511 
512  if (new_enables)
513  {
514  for( size_t i=0; i<new_enables->enables().size(); ++i )
515  {
516  const EEnable& capability = new_enables->enables()[i];
517  mNewEnableSet->append(capability);
518  if(!mCurrentEnableSet->hasKey(capability))
519  {
520  glEnable( Translate_Enable[capability] );
521  #ifndef NDEBUG
522  if (glGetError() != GL_NO_ERROR)
523  {
524  Log::error( Say("An unsupported capability has been enabled: %s.\n") << Translate_Enable_String[capability]);
525  }
526  #endif
527  }
528  }
529  }
530 
531  for(EEnable* capability = mCurrentEnableSet->begin(); capability != mCurrentEnableSet->end(); ++capability)
532  {
533  if (!mNewEnableSet->hasKey(*capability))
534  {
535  glDisable( Translate_Enable[*capability] );
536  #ifndef NDEBUG
537  if (glGetError() != GL_NO_ERROR)
538  {
539  Log::error( Say("An unsupported capability has been disabled: %s.\n") << Translate_Enable_String[*capability]);
540  }
541  #endif
542  }
543  }
544 
545  std::swap(mNewEnableSet, mCurrentEnableSet);
546 }
547 //------------------------------------------------------------------------------
548 // MIC FIXME: `camera` can also be taken away
549 void OpenGLContext::applyRenderStates( const RenderStateSet* new_rs, const Camera* camera)
550 {
551  VL_CHECK_OGL()
552 
553  mNewRenderStateSet->clear();
554 
555  if (new_rs)
556  {
557  for( size_t i=0; i<new_rs->renderStatesCount(); ++i )
558  {
559  const RenderStateSlot& rs = new_rs->renderStates()[i];
560  mNewRenderStateSet->append(rs.type(), rs);
561  if ( ! mCurrentRenderStateSet->hasKey(rs.type()) || rs.mRS.get() != mCurrentRenderStateSet->valueFromKey( rs.type() ).mRS.get() )
562  {
563  VL_CHECK(rs.mRS.get());
564  rs.apply(camera, this); VL_CHECK_OGL()
565  }
566  }
567  }
568 
569  for( RenderStateSlot* rs = mCurrentRenderStateSet->begin(); rs != mCurrentRenderStateSet->end(); ++rs )
570  {
571  if ( ! mNewRenderStateSet->hasKey( rs->type() ) )
572  {
573  mDefaultRenderStates[rs->type()].apply(NULL, this); VL_CHECK_OGL()
574  }
575  }
576 
577  std::swap(mNewRenderStateSet, mCurrentRenderStateSet);
578 }
579 //------------------------------------------------------------------------------
580 void OpenGLContext::setupDefaultRenderStates()
581 {
583  {
584  mDefaultRenderStates[RS_Color] = RenderStateSlot(new Color, 0);
585  mDefaultRenderStates[RS_SecondaryColor] = RenderStateSlot(new SecondaryColor, 0);
586  mDefaultRenderStates[RS_Normal] = RenderStateSlot(new Normal, 0);
587 
588  mDefaultRenderStates[RS_AlphaFunc] = RenderStateSlot(new AlphaFunc, 0);
589  mDefaultRenderStates[RS_Fog] = RenderStateSlot(new Fog, 0);
590  mDefaultRenderStates[RS_ShadeModel] = RenderStateSlot(new ShadeModel, 0);
591  mDefaultRenderStates[RS_LightModel] = RenderStateSlot(new LightModel, 0);
592  mDefaultRenderStates[RS_Material] = RenderStateSlot(new Material, 0);
594  {
595  mDefaultRenderStates[RS_PixelTransfer] = RenderStateSlot(new PixelTransfer, 0);
596  mDefaultRenderStates[RS_LineStipple] = RenderStateSlot(new LineStipple, 0);
597  mDefaultRenderStates[RS_PolygonStipple] = RenderStateSlot(new PolygonStipple, 0);
598  }
599 
600  mDefaultRenderStates[RS_Light0] = RenderStateSlot(new Light, 0); mDefaultRenderStates[RS_Light0].mRS->as<Light>()->setEnabled(false);
601  mDefaultRenderStates[RS_Light1] = RenderStateSlot(new Light, 1); mDefaultRenderStates[RS_Light1].mRS->as<Light>()->setEnabled(false);
602  mDefaultRenderStates[RS_Light2] = RenderStateSlot(new Light, 2); mDefaultRenderStates[RS_Light2].mRS->as<Light>()->setEnabled(false);
603  mDefaultRenderStates[RS_Light3] = RenderStateSlot(new Light, 3); mDefaultRenderStates[RS_Light3].mRS->as<Light>()->setEnabled(false);
604  mDefaultRenderStates[RS_Light4] = RenderStateSlot(new Light, 4); mDefaultRenderStates[RS_Light4].mRS->as<Light>()->setEnabled(false);
605  mDefaultRenderStates[RS_Light5] = RenderStateSlot(new Light, 5); mDefaultRenderStates[RS_Light5].mRS->as<Light>()->setEnabled(false);
606  mDefaultRenderStates[RS_Light6] = RenderStateSlot(new Light, 6); mDefaultRenderStates[RS_Light6].mRS->as<Light>()->setEnabled(false);
607  mDefaultRenderStates[RS_Light7] = RenderStateSlot(new Light, 7); mDefaultRenderStates[RS_Light7].mRS->as<Light>()->setEnabled(false);
608 
609  mDefaultRenderStates[RS_ClipPlane0] = RenderStateSlot(new ClipPlane, 0); mDefaultRenderStates[RS_ClipPlane0].mRS->as<ClipPlane>()->setEnabled(false);
610  mDefaultRenderStates[RS_ClipPlane1] = RenderStateSlot(new ClipPlane, 1); mDefaultRenderStates[RS_ClipPlane1].mRS->as<ClipPlane>()->setEnabled(false);
611  mDefaultRenderStates[RS_ClipPlane2] = RenderStateSlot(new ClipPlane, 2); mDefaultRenderStates[RS_ClipPlane2].mRS->as<ClipPlane>()->setEnabled(false);
612  mDefaultRenderStates[RS_ClipPlane3] = RenderStateSlot(new ClipPlane, 3); mDefaultRenderStates[RS_ClipPlane3].mRS->as<ClipPlane>()->setEnabled(false);
613  mDefaultRenderStates[RS_ClipPlane4] = RenderStateSlot(new ClipPlane, 4); mDefaultRenderStates[RS_ClipPlane4].mRS->as<ClipPlane>()->setEnabled(false);
614  mDefaultRenderStates[RS_ClipPlane5] = RenderStateSlot(new ClipPlane, 5); mDefaultRenderStates[RS_ClipPlane5].mRS->as<ClipPlane>()->setEnabled(false);
615  }
616 
618  mDefaultRenderStates[RS_BlendColor] = RenderStateSlot(new BlendColor, 0);
619 
621  mDefaultRenderStates[RS_BlendEquation] = RenderStateSlot(new BlendEquation, 0);
622 
623  if(!Has_GLES)
624  mDefaultRenderStates[RS_PolygonMode] = RenderStateSlot(new PolygonMode, 0);
625 
627  {
628  mDefaultRenderStates[RS_LogicOp] = RenderStateSlot(new LogicOp, 0);
629  mDefaultRenderStates[RS_PointSize] = RenderStateSlot(new PointSize, 0);
630  }
631 
632  mDefaultRenderStates[RS_PolygonOffset] = RenderStateSlot(new PolygonOffset, 0);
633  mDefaultRenderStates[RS_BlendFunc] = RenderStateSlot(new BlendFunc, 0);
634  mDefaultRenderStates[RS_ColorMask] = RenderStateSlot(new ColorMask, 0);
635  mDefaultRenderStates[RS_CullFace] = RenderStateSlot(new CullFace, 0);
636  mDefaultRenderStates[RS_DepthFunc] = RenderStateSlot(new DepthFunc, 0);
637  mDefaultRenderStates[RS_DepthMask] = RenderStateSlot(new DepthMask, 0);
638  mDefaultRenderStates[RS_DepthRange] = RenderStateSlot(new DepthRange, 0);
639  mDefaultRenderStates[RS_FrontFace] = RenderStateSlot(new FrontFace, 0);
640  mDefaultRenderStates[RS_Hint] = RenderStateSlot(new Hint, 0);
641  mDefaultRenderStates[RS_LineWidth] = RenderStateSlot(new LineWidth, 0);
642 
643  if (Has_GL_ARB_point_parameters||Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0||Has_GLES_Version_1_1) // note GLES 2.x is excluded
644  mDefaultRenderStates[RS_PointParameter] = RenderStateSlot(new PointParameter, 0);
645 
647  mDefaultRenderStates[RS_SampleCoverage] = RenderStateSlot(new SampleCoverage, 0);
648 
649  mDefaultRenderStates[RS_StencilFunc] = RenderStateSlot(new StencilFunc, 0);
650  mDefaultRenderStates[RS_StencilMask] = RenderStateSlot(new StencilMask, 0);
651  mDefaultRenderStates[RS_StencilOp] = RenderStateSlot(new StencilOp, 0);
652  mDefaultRenderStates[RS_GLSLProgram] = RenderStateSlot(new GLSLProgram, 0);
653 
654  for(int i=0; i<textureImageUnitCount(); ++i) {
655  mDefaultRenderStates[RS_TextureSampler + i] = RenderStateSlot(new TextureSampler, i);
656  }
657 
659  {
660  for(int i=0; i<textureCoordCount(); ++i)
661  {
662  // TexGen under GLES is supported only if GL_OES_texture_cube_map is present
663  if( ! Has_GLES_Version_1_1 || Has_GL_OES_texture_cube_map) {
664  mDefaultRenderStates[RS_TexGen + i] = RenderStateSlot(new TexGen, i);
665  }
666  mDefaultRenderStates[RS_TexEnv + i] = RenderStateSlot(new TexEnv, i);
667  mDefaultRenderStates[RS_TextureMatrix + i] = RenderStateSlot(new TextureMatrix, i);
668  }
669  }
670 
671  VL_CHECK_OGL();
672 
673  // applies default render states backwards so we don't need to call VL_glActiveTexture(GL_TEXTURE0) at the end.
674  for( int i=RS_RenderStateCount; i--; )
675  {
676  // the empty ones are the ones that are not supported by the current OpenGL implementation (too old or Core profile)
677  if (mDefaultRenderStates[i].mRS)
678  {
679  mDefaultRenderStates[i].apply(NULL, this); VL_CHECK_OGL();
680  }
681  }
682 }
683 //-----------------------------------------------------------------------------
685 {
686  mCurrentRenderStateSet->clear();
687  memset( mTexUnitBinding, 0, sizeof( mTexUnitBinding ) ); // set to unknown texture target
688 }
689 //-----------------------------------------------------------------------------
691 {
692  mCurrentEnableSet->clear();
693 }
694 //------------------------------------------------------------------------------
695 bool OpenGLContext::isCleanState(bool verbose)
696 {
697  VL_CHECK_OGL();
698  String error_msg;
699 
700  // check default VAO is active
701  if ( Is_OpenGL_Core_Profile && glBindVertexArray ) {
702  int vao = 0;
703  glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &vao ); VL_CHECK_OGL();
704  if (vao != (int)mDefaultVAO ) {
705  error_msg += Say("Current VAO (%n) is not the default one (%n)!\n") << vao << mDefaultVAO;
706  glBindVertexArray( mDefaultVAO ); VL_CHECK_OGL();
707  }
708  }
709 
710  // everything must be disabled except GL_DITHER and GL_MULTISAMPLE
711  for( unsigned i=0; i<EN_EnableCount; ++i )
712  {
713  if (!Is_Enable_Supported[i])
714  continue;
715 
716  if (i == EN_DITHER || i == EN_MULTISAMPLE)
717  continue;
718 
719  GLboolean enabled = glIsEnabled( Translate_Enable[i] ); VL_CHECK_OGL();
720 
721  if (enabled)
722  {
723  error_msg += Say(" - Capability %s was enabled!\n") << Translate_Enable_String[i];
724  glDisable(Translate_Enable[i]);
725  }
726  }
727 
729  {
730  int max_lights = 0;
731  glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
732 
733  for( int i=0; i<max_lights; ++i)
734  {
735  if (glIsEnabled(GL_LIGHT0+i))
736  {
737  error_msg += Say(" - GL_LIGHT%n was enabled!\n") << i;
738  glDisable(GL_LIGHT0+i);
739  }
740  }
741 
742  // OpenGL requires 6 planes but GLES 1.x requires only 1.
743  int max_planes = 0;
744  glGetIntegerv(GL_MAX_CLIP_PLANES, &max_planes);
745 
746  for( int i=0; i<max_planes; ++i)
747  {
748  if (glIsEnabled(GL_CLIP_PLANE0+i))
749  {
750  error_msg += Say(" - GL_CLIP_PLANE%n was enabled!\n") << i;
751  glDisable(GL_CLIP_PLANE0+i);
752  }
753  }
754  }
755 
756  if (Has_Primitive_Restart && glIsEnabled(GL_PRIMITIVE_RESTART))
757  {
758  error_msg += " - GL_PRIMITIVE_RESTART was enabled!\n";
759  glDisable(GL_PRIMITIVE_RESTART);
760  }
761 
762  if(Has_Multitexture)
763  {
764  int active_tex = -1;
765  // mic fixme: PVR emulator bug? returns always 1.
766 #if !defined(VL_OPENGL_ES2)
767  glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex); VL_CHECK_OGL();
768  active_tex -= GL_TEXTURE0;
769  if (active_tex != 0)
770  {
771  error_msg += Say(" - Active texture unit is GL_TEXTURE%n instead of GL_TEXTURE0!\n") << active_tex;
772  glActiveTexture(GL_TEXTURE0);
773  }
774 #endif
775 
777  {
778  active_tex = -1;
779  glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &active_tex); VL_CHECK_OGL();
780  active_tex -= GL_TEXTURE0;
781  if (active_tex != 0)
782  {
783  error_msg += Say(" - Active client texture unit is GL_TEXTURE%n instead of GL_TEXTURE0!\n") << active_tex;
784  glClientActiveTexture(GL_TEXTURE0);
785  }
786  }
787  }
788 
789  VL_CHECK_OGL()
790 
791  /* We only check the subset of tex-units supported also by glClientActiveTexture() */
792  // Find the minimum of the max texture units supported, starting at 16
793  int coord_count = 16;
794  if (Has_GL_ARB_multitexture||Has_GL_Version_1_3||Has_GLES_Version_1_1)
795  {
796  int max_tmp = 0;
797  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
798  coord_count = max_tmp < coord_count ? max_tmp : coord_count;
799  }
800 
801  VL_CHECK_OGL()
802 
803  if (Has_GLSL) // for GL >= 2.0
804  {
805  int max_tmp = 0;
806  glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_tmp); VL_CHECK_OGL();
807  coord_count = max_tmp < coord_count ? max_tmp : coord_count;
808  }
809 
810  if (Has_GL_Version_2_0) // for GL == 2.x && compatible higher
811  {
812  int max_tmp = 0;
813  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
814  coord_count = max_tmp < coord_count ? max_tmp : coord_count;
815  }
816 
817  VL_CHECK_OGL()
818 
819  while(coord_count--)
820  {
821  VL_CHECK_OGL()
822  VL_glActiveTexture(GL_TEXTURE0+coord_count); VL_CHECK_OGL()
823 
825  {
826  VL_glClientActiveTexture(GL_TEXTURE0+coord_count); VL_CHECK_OGL()
827 
828  float matrix[16];
829  float imatrix[16];
830  glGetFloatv(GL_TEXTURE_MATRIX, matrix); VL_CHECK_OGL()
831  glMatrixMode(GL_TEXTURE); VL_CHECK_OGL()
832  glLoadIdentity(); VL_CHECK_OGL()
833  glGetFloatv(GL_TEXTURE_MATRIX, imatrix); VL_CHECK_OGL()
834  // glLoadMatrixf(matrix); VL_CHECK_OGL() // we keep the identity
835  if (memcmp(matrix,imatrix,sizeof(matrix)) != 0)
836  {
837  error_msg += Say(" - Texture matrix was not set to identity on texture unit %n!\n") << coord_count;
838  }
839 
840  if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
841  {
842  error_msg += Say(" - GL_TEXTURE_COORD_ARRAY was enabled on texture unit %n!\n") << coord_count;
843  glDisable(GL_TEXTURE_COORD_ARRAY);
844  }
845 
846  // check that all texture targets are disabled and bound to texture #0
847 
848  if (!Has_GLES)
849  {
850  if (glIsEnabled(GL_TEXTURE_1D))
851  {
852  error_msg += Say(" - GL_TEXTURE_1D was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
853  glDisable(GL_TEXTURE_1D);
854  }
855 
856  GLint bound_tex = 0;
857  glGetIntegerv(GL_TEXTURE_BINDING_1D, &bound_tex); VL_CHECK_OGL()
858  if (bound_tex != 0)
859  {
860  error_msg += Say(" - GL_TEXTURE_BINDING_1D != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
861  }
862  }
863 
864  if (glIsEnabled(GL_TEXTURE_2D))
865  {
866  error_msg += Say(" - GL_TEXTURE_2D was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
867  glDisable(GL_TEXTURE_2D);
868  }
869  }
870 
871  GLint bound_tex = 0;
872  glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_tex); VL_CHECK_OGL()
873  if (bound_tex != 0)
874  {
875  error_msg += Say(" - GL_TEXTURE_BINDING_2D != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
876  }
877 
879  {
880  if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_TEXTURE_RECTANGLE))
881  {
882  error_msg += Say(" - GL_TEXTURE_RECTANGLE was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
883  glDisable(GL_TEXTURE_RECTANGLE);
884  }
885 
886  bound_tex = 0;
887  glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE, &bound_tex); VL_CHECK_OGL()
888  if (bound_tex != 0)
889  {
890  error_msg += Say(" - GL_TEXTURE_BINDING_RECTANGLE != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
891  }
892  }
893 
894  if (Has_Texture_3D)
895  {
896  if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_TEXTURE_3D))
897  {
898  error_msg += Say(" - GL_TEXTURE_3D was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
899  glDisable(GL_TEXTURE_3D);
900  }
901 
902  bound_tex = 0;
903  glGetIntegerv(GL_TEXTURE_BINDING_3D, &bound_tex); VL_CHECK_OGL()
904  if (bound_tex != 0)
905  {
906  error_msg += Say(" - GL_TEXTURE_BINDING_3D != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
907  }
908  }
909 
911  {
912  if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_TEXTURE_CUBE_MAP))
913  {
914  error_msg += Say(" - GL_TEXTURE_CUBE_MAP was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
915  glDisable(GL_TEXTURE_CUBE_MAP);
916  }
917 
918  bound_tex = 0;
919  glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &bound_tex); VL_CHECK_OGL()
920  if (bound_tex != 0)
921  {
922  error_msg += Say(" - GL_TEXTURE_BINDING_CUBE_MAP != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
923  }
924  }
925 
926  if (Has_Texture_Array)
927  {
928  bound_tex = 0;
929  glGetIntegerv(GL_TEXTURE_BINDING_1D_ARRAY, &bound_tex);
930  if (bound_tex != 0)
931  {
932  error_msg += Say(" - GL_TEXTURE_BINDING_1D_ARRAY != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
933  }
934 
935  bound_tex = 0;
936  glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, &bound_tex);
937  if (bound_tex != 0)
938  {
939  error_msg += Say(" - GL_TEXTURE_BINDING_2D_ARRAY != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
940  }
941  }
942 
944  {
945  bound_tex = 0;
946  glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &bound_tex);
947  if (bound_tex != 0)
948  {
949  error_msg += Say(" - GL_TEXTURE_BINDING_2D_MULTISAMPLE != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
950  }
951 
952  bound_tex = 0;
953  glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, &bound_tex);
954  if (bound_tex != 0)
955  {
956  error_msg += Say(" - GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
957  }
958  }
959 
960  if (Has_Texture_Buffer)
961  {
962  bound_tex = 0;
963  glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &bound_tex);
964  if (bound_tex != 0)
965  {
966  error_msg += Say(" - GL_TEXTURE_BINDING_BUFFER != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
967  }
968  }
969 
971  {
972 #if defined(VL_OPENGL)
973  if (glIsEnabled(GL_TEXTURE_GEN_S))
974  {
975  error_msg += Say(" - GL_TEXTURE_GEN_S was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
976  glDisable(GL_TEXTURE_GEN_S);
977  }
978 
979  if (glIsEnabled(GL_TEXTURE_GEN_T))
980  {
981  error_msg += Say(" - GL_TEXTURE_GEN_T was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
982  glDisable(GL_TEXTURE_GEN_T);
983  }
984 
985  if (glIsEnabled(GL_TEXTURE_GEN_R))
986  {
987  error_msg += Say(" - GL_TEXTURE_GEN_R was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
988  glDisable(GL_TEXTURE_GEN_R);
989  }
990 
991  if (glIsEnabled(GL_TEXTURE_GEN_Q))
992  {
993  error_msg += Say(" - GL_TEXTURE_GEN_Q was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
994  glDisable(GL_TEXTURE_GEN_Q);
995  }
996 #elif defined(VL_OPENGL_ES1)
997  if (Has_GL_OES_texture_cube_map && glIsEnabled(GL_TEXTURE_GEN_STR_OES))
998  {
999  error_msg += Say(" - GL_TEXTURE_GEN_STR_OES was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
1000  glDisable(GL_TEXTURE_GEN_STR_OES);
1001  }
1002 #endif
1003  }
1004  }
1005 
1006  if (Has_GL_Version_1_1 && glIsEnabled(GL_COLOR_MATERIAL)) // excludes also GLES
1007  {
1008  error_msg += " - GL_COLOR_MATERIAL was enabled!\n";
1009  glDisable(GL_COLOR_MATERIAL);
1010  }
1011 
1012  if (Has_GL_Version_1_4 || Has_GL_EXT_fog_coord) // excludes also GLES 1.x
1013  {
1014  if (glIsEnabled(GL_FOG_COORD_ARRAY))
1015  {
1016  error_msg += " - GL_FOG_COORD_ARRAY was enabled!\n";
1017  glDisable(GL_FOG_COORD_ARRAY);
1018  }
1019  }
1020 
1021  if (Has_GL_Version_1_4 || Has_GL_EXT_secondary_color) // excludes also GLES 1.x
1022  {
1023  if (glIsEnabled(GL_SECONDARY_COLOR_ARRAY))
1024  {
1025  error_msg += " - GL_SECONDARY_COLOR_ARRAY was enabled!\n";
1026  glDisable(GL_SECONDARY_COLOR_ARRAY);
1027  }
1028  }
1029 
1030  if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_COLOR_ARRAY)) // includes GLES 1.x
1031  {
1032  error_msg += " - GL_COLOR_ARRAY was enabled!\n";
1033  glDisable(GL_COLOR_ARRAY);
1034  }
1035 
1036  if (Has_GL_Version_1_1 && glIsEnabled(GL_EDGE_FLAG_ARRAY)) // excludes GLES
1037  {
1038  error_msg += " - GL_EDGE_FLAG_ARRAY was enabled!\n";
1039  glDisable(GL_EDGE_FLAG_ARRAY);
1040  }
1041 
1042  if (Has_GL_Version_1_1 && glIsEnabled(GL_INDEX_ARRAY)) // excludes GLES
1043  {
1044  error_msg += " - GL_INDEX_ARRAY was enabled!\n";
1045  glDisable(GL_INDEX_ARRAY);
1046  }
1047 
1048  if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_NORMAL_ARRAY)) // includes GLES 1.x
1049  {
1050  error_msg += " - GL_NORMAL_ARRAY was enabled!\n";
1051  glDisable(GL_NORMAL_ARRAY);
1052  }
1053 
1054  if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_VERTEX_ARRAY)) // includes GLES 1.x
1055  {
1056  error_msg += " - GL_VERTEX_ARRAY was enabled!\n";
1057  glDisable(GL_VERTEX_ARRAY);
1058  }
1059 
1060  if (glIsEnabled(GL_SCISSOR_TEST))
1061  {
1062  error_msg += " - GL_SCISSOR_TEST was enabled!\n";
1063  glDisable(GL_SCISSOR_TEST);
1064  }
1065 
1066  GLint max_vert_attribs = 0;
1067  if (Has_GLSL)
1068  glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vert_attribs);
1069  for(int i=0; i<max_vert_attribs; ++i)
1070  {
1071  GLint is_enabled = 0;
1072  glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &is_enabled);
1073  if (is_enabled)
1074  {
1075  error_msg += Say(" - GL_VERTEX_ATTRIB_ARRAY #%n is enabled!\n") << i;
1076  }
1077  }
1078 
1079  if (Has_GL_ARB_imaging)
1080  {
1081  if (glIsEnabled(GL_HISTOGRAM))
1082  {
1083  error_msg += " - GL_HISTOGRAM was enabled!\n";
1084  glDisable(GL_HISTOGRAM);
1085  }
1086 
1087  if (glIsEnabled(GL_MINMAX))
1088  {
1089  error_msg += " - GL_MINMAX was enabled!\n";
1090  glDisable(GL_MINMAX);
1091  }
1092  }
1093 
1094  // we expect these settings for the default blending equation
1095 #if defined(VL_OPENGL_ES2)
1096  GLint blend_src = 0;
1097  GLint blend_dst = 0;
1098  glGetIntegerv( GL_BLEND_SRC_RGB, &blend_src ); VL_CHECK_OGL();
1099  glGetIntegerv( GL_BLEND_DST_RGB, &blend_dst ); VL_CHECK_OGL();
1100  if (blend_src != GL_SRC_ALPHA)
1101  {
1102  error_msg += " - GL_BLEND_SRC is not GL_SRC_ALPHA!\n";
1103  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1104  }
1105  if (blend_dst != GL_ONE_MINUS_SRC_ALPHA)
1106  {
1107  error_msg += " - GL_BLEND_DST is not GL_ONE_MINUS_SRC_ALPHA!\n";
1108  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1109  }
1110 #else
1111  GLint blend_src = 0;
1112  GLint blend_dst = 0;
1113  glGetIntegerv( GL_BLEND_SRC, &blend_src ); VL_CHECK_OGL();
1114  glGetIntegerv( GL_BLEND_DST, &blend_dst ); VL_CHECK_OGL();
1115  if (blend_src != GL_SRC_ALPHA)
1116  {
1117  error_msg += " - GL_BLEND_SRC is not GL_SRC_ALPHA!\n";
1118  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1119  }
1120  if (blend_dst != GL_ONE_MINUS_SRC_ALPHA)
1121  {
1122  error_msg += " - GL_BLEND_DST is not GL_ONE_MINUS_SRC_ALPHA!\n";
1123  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1124  }
1125 #endif
1126 
1127  // buffer object bindings
1128 
1129  GLint buf_bind = 0;
1130  if (Has_BufferObject)
1131  {
1132  glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
1133  if (buf_bind != 0)
1134  {
1135  error_msg += " - GL_ARRAY_BUFFER_BINDING should be 0!\n";
1136  }
1137  buf_bind = 0;
1138  glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
1139  if (buf_bind != 0)
1140  {
1141  error_msg += " - GL_ELEMENT_ARRAY_BUFFER_BINDING should be 0!\n";
1142  }
1143  }
1144  if (Has_GL_Version_2_1)
1145  {
1146  buf_bind = 0;
1147  glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
1148  if (buf_bind != 0)
1149  {
1150  error_msg += " - GL_PIXEL_PACK_BUFFER_BINDING should be 0!\n";
1151  }
1152  buf_bind = 0;
1153  glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
1154  if (buf_bind != 0)
1155  {
1156  error_msg += " - GL_PIXEL_UNPACK_BUFFER_BINDING should be 0!\n";
1157  }
1158  }
1159  if (Has_GL_ARB_uniform_buffer_object)
1160  {
1161  buf_bind = 0;
1162  glGetIntegerv(GL_UNIFORM_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
1163  if (buf_bind != 0)
1164  {
1165  error_msg += " - GL_UNIFORM_BUFFER_BINDING should be 0!\n";
1166  }
1167  }
1169  {
1170  buf_bind = 0;
1171  glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
1172  if (buf_bind != 0)
1173  {
1174  error_msg += " - GL_TRANSFORM_FEEDBACK_BUFFER_BINDING should be 0!\n";
1175  }
1176  }
1177 
1178  #if 0
1179  // check viewport
1180  GLint viewport[4] = {0,0,0,0};
1181  glGetIntegerv(GL_VIEWPORT, viewport);
1182  if (viewport[2] * viewport[3] == 1)
1183  {
1184  error_msg += " - Viewport dimension is 1 pixel!\n"
1185  "Did you forget to call camera()->viewport()->setWidth()/setHeight() upon window resize event?\n";
1186  }
1187  #endif
1188 
1189  GLboolean write_mask[4];
1190  glGetBooleanv(GL_COLOR_WRITEMASK, write_mask); VL_CHECK_OGL();
1191  if( !write_mask[0] || !write_mask[1] || !write_mask[2] || !write_mask[3] )
1192  {
1193  error_msg += " - Color write-mask should be glColorMask(GL_TRUE ,GL_TRUE, GL_TRUE, GL_TRUE)!\n";
1194  glColorMask(GL_TRUE ,GL_TRUE, GL_TRUE, GL_TRUE);
1195  }
1196 
1197  glGetBooleanv(GL_DEPTH_WRITEMASK, write_mask); VL_CHECK_OGL();
1198  if ( !write_mask[0] )
1199  {
1200  error_msg += " - Depth write-mask should be glDepthMask(GL_TRUE)!\n";
1201  glDepthMask(GL_TRUE);
1202  }
1203 
1204 #if defined(VL_OPENGL)
1205  GLint poly_mode[] = { GL_FILL, GL_FILL };
1206  glGetIntegerv(GL_POLYGON_MODE, poly_mode); VL_CHECK_OGL();
1207  if ( poly_mode[0] != GL_FILL || poly_mode[1] != GL_FILL )
1208  {
1209  error_msg += " - Polygon mode should be glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)!\n";
1210  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); VL_CHECK_OGL();
1211  }
1212 #endif
1213 
1214  if (!error_msg.empty() && verbose)
1215  {
1216  Log::error("Dirty OpenGL context state:\n");
1217  Log::error(error_msg);
1218  Log::error("To disable this check use globalSettings()->setCheckOpenGLStates(false);\n");
1219  Log::error( Say("Driver info: %s, %s, OpenGL %s\n")
1220  << glGetString(GL_VENDOR) << glGetString(GL_RENDERER) << glGetString(GL_VERSION) );
1221  }
1222 
1223  VL_CHECK_OGL();
1224 
1225  return error_msg.empty();
1226 }
1227 //-----------------------------------------------------------------------------
1229 {
1230  if (!u1 || !u2)
1231  return false;
1232 
1233  // compile the map
1234  std::set<std::string> name_set;
1235  for( size_t i=0; i<u1->uniforms().size(); ++i )
1236  name_set.insert( u1->uniforms()[i]->name() );
1237 
1238  bool ok = false;
1239  // check the map
1240  for( size_t j=0; j<u2->uniforms().size(); ++j )
1241  if ( name_set.find( u2->uniforms()[j]->name() ) != name_set.end() )
1242  {
1243  vl::Log::error( Say("Uniform name collision detected: %s\n") << u2->uniforms()[j]->name() );
1244  ok = true;
1245  }
1246 
1247  return ok;
1248 }
1249 //-----------------------------------------------------------------------------
1251 {
1252  // Check that the OpenGL state is clear.
1253  // If this fails use VL_CHECK_OGL to make sure your application does not generate OpenGL errors.
1254  // See also glGetError() -> http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml
1255  VL_CHECK_OGL();
1256 
1257  // perform extra OpenGL environment sanity check
1258  if (globalSettings()->checkOpenGLStates())
1259  isCleanState(true);
1260 
1261  VL_glBindFramebuffer(GL_FRAMEBUFFER, 0); VL_CHECK_OGL();
1262 
1263  // not existing under OpenGL ES 1 and 2
1264 #if defined(VL_OPENGL)
1265  if ( hasDoubleBuffer() )
1266  {
1267  glDrawBuffer(GL_BACK); VL_CHECK_OGL();
1268  glReadBuffer(GL_BACK); VL_CHECK_OGL();
1269  }
1270  else
1271  {
1272  glDrawBuffer(GL_FRONT); VL_CHECK_OGL();
1273  glReadBuffer(GL_FRONT); VL_CHECK_OGL();
1274  }
1275 #endif
1276 
1277  // these need to be cleaned up only when rendering starts
1278 
1279  if (start_or_finish == RCS_RenderingStarted)
1280  {
1281  // reset internal VL enables & render states tables
1282  resetEnables();
1283  resetRenderStates();
1284 
1285  // default VAO needed for OpenGL Core profiles
1286  if ( Is_OpenGL_Core_Profile && mDefaultVAO && glGenVertexArrays && glBindVertexArray ) {
1287  glBindVertexArray( mDefaultVAO ); VL_CHECK_OGL();
1288  }
1289 
1290  // reset Vertex Attrib Set tables and also calls "glBindBuffer(GL_ARRAY_BUFFER, 0)"
1291  bindVAS(NULL, false, true); VL_CHECK_OGL();
1292  }
1293 }
1294 //-----------------------------------------------------------------------------
1295 void OpenGLContext::bindVAS_Fixed(const IVertexAttribSet* vas, bool use_bo) {
1296  int buf_obj = 0;
1297  const unsigned char* ptr = 0;
1298  bool enabled = false;
1299 
1300  // ----- vertex array -----
1301 
1302  enabled = vas->vertexArray() != NULL;
1303  if ( mVertexArray.mEnabled || enabled )
1304  {
1305  if (enabled)
1306  {
1307  if ( use_bo && vas->vertexArray()->bufferObject()->handle() )
1308  {
1309  buf_obj = vas->vertexArray()->bufferObject()->handle();
1310  ptr = 0;
1311  }
1312  else
1313  {
1314  buf_obj = 0;
1315  ptr = vas->vertexArray()->bufferObject()->ptr();
1316  }
1317  if ( mVertexArray.mPtr != ptr || mVertexArray.mBufferObject != buf_obj )
1318  {
1319  if (!mVertexArray.mEnabled)
1320  {
1321  glEnableClientState(GL_VERTEX_ARRAY); VL_CHECK_OGL();
1322  }
1323  // mic fixme:
1324  // Note: for the moment we threat glBindBuffer and glVertexPointer as an atomic operation.
1325  // In the future we'll want to eliminate all direct calls to glBindBuffer and similar an
1326  // go through the OpenGLContext that will lazily do everything.
1327  VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
1328  glVertexPointer((int)vas->vertexArray()->glSize(), vas->vertexArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
1329  mVertexArray.mPtr = ptr;
1330  mVertexArray.mBufferObject = buf_obj;
1331  }
1332  }
1333  else
1334  {
1335  glDisableClientState(GL_VERTEX_ARRAY); VL_CHECK_OGL();
1336  mVertexArray.mPtr = 0;
1337  mVertexArray.mBufferObject = 0;
1338  }
1339  mVertexArray.mEnabled = enabled;
1340  }
1341 
1342  // ----- normal array -----
1343 
1344  enabled = vas->normalArray() != NULL;
1345  if ( mNormalArray.mEnabled || enabled )
1346  {
1347  if (enabled)
1348  {
1349  if ( use_bo && vas->normalArray()->bufferObject()->handle() )
1350  {
1351  buf_obj = vas->normalArray()->bufferObject()->handle();
1352  ptr = 0;
1353  }
1354  else
1355  {
1356  buf_obj = 0;
1357  ptr = vas->normalArray()->bufferObject()->ptr();
1358  }
1359  if ( mNormalArray.mPtr != ptr || mNormalArray.mBufferObject != buf_obj )
1360  {
1361  if (!mNormalArray.mEnabled)
1362  {
1363  glEnableClientState(GL_NORMAL_ARRAY); VL_CHECK_OGL();
1364  }
1365  VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
1366  glNormalPointer(vas->normalArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
1367  mNormalArray.mPtr = ptr;
1368  mNormalArray.mBufferObject = buf_obj;
1369  }
1370  }
1371  else
1372  {
1373  glDisableClientState(GL_NORMAL_ARRAY); VL_CHECK_OGL();
1374 
1375  // restore constant normal
1376  glNormal3f( mNormal.x(), mNormal.y(), mNormal.z() );
1377 
1378  mNormalArray.mPtr = 0;
1379  mNormalArray.mBufferObject = 0;
1380  }
1381  mNormalArray.mEnabled = enabled;
1382  }
1383 
1384  // ----- color array -----
1385 
1386  enabled = vas->colorArray() != NULL;
1387  if ( mColorArray.mEnabled || enabled )
1388  {
1389  if (enabled)
1390  {
1391  if ( use_bo && vas->colorArray()->bufferObject()->handle() )
1392  {
1393  buf_obj = vas->colorArray()->bufferObject()->handle();
1394  ptr = 0;
1395  }
1396  else
1397  {
1398  buf_obj = 0;
1399  ptr = vas->colorArray()->bufferObject()->ptr();
1400  }
1401  if ( mColorArray.mPtr != ptr || mColorArray.mBufferObject != buf_obj )
1402  {
1403  if (!mColorArray.mEnabled)
1404  {
1405  glEnableClientState(GL_COLOR_ARRAY); VL_CHECK_OGL();
1406  }
1407  VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
1408  glColorPointer((int)vas->colorArray()->glSize(), vas->colorArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
1409  mColorArray.mPtr = ptr;
1410  mColorArray.mBufferObject = buf_obj;
1411  }
1412  }
1413  else
1414  {
1415  glDisableClientState(GL_COLOR_ARRAY); VL_CHECK_OGL();
1416 
1417  // restore constant color
1418  glColor4f( mColor.r(), mColor.g(), mColor.b(), mColor.a() );
1419 
1420  mColorArray.mPtr = 0;
1421  mColorArray.mBufferObject = 0;
1422  }
1423  mColorArray.mEnabled = enabled;
1424  }
1425 
1426  // ----- secondary color array -----
1427 
1428  enabled = vas->secondaryColorArray() != NULL;
1429  if ( mSecondaryColorArray.mEnabled || enabled )
1430  {
1431  if (enabled)
1432  {
1433  if ( use_bo && vas->secondaryColorArray()->bufferObject()->handle() )
1434  {
1435  buf_obj = vas->secondaryColorArray()->bufferObject()->handle();
1436  ptr = 0;
1437  }
1438  else
1439  {
1440  buf_obj = 0;
1441  ptr = vas->secondaryColorArray()->bufferObject()->ptr();
1442  }
1443  if ( mSecondaryColorArray.mPtr != ptr || mSecondaryColorArray.mBufferObject != buf_obj )
1444  {
1445  if (!mSecondaryColorArray.mEnabled)
1446  {
1447  glEnableClientState(GL_SECONDARY_COLOR_ARRAY); VL_CHECK_OGL();
1448  }
1449  VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
1450  glSecondaryColorPointer((int)vas->secondaryColorArray()->glSize(), vas->secondaryColorArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
1451  mSecondaryColorArray.mPtr = ptr;
1452  mSecondaryColorArray.mBufferObject = buf_obj;
1453  }
1454  }
1455  else
1456  {
1457  glDisableClientState(GL_SECONDARY_COLOR_ARRAY); VL_CHECK_OGL();
1458 
1459  // restore constant secondary color
1460  VL_glSecondaryColor3f( mSecondaryColor.r(), mSecondaryColor.g(), mSecondaryColor.b() );
1461 
1462  mSecondaryColorArray.mPtr = 0;
1463  mSecondaryColorArray.mBufferObject = 0;
1464  }
1465  mSecondaryColorArray.mEnabled = enabled;
1466  }
1467 
1468  // ----- fog array -----
1469 
1470  enabled = vas->fogCoordArray() != NULL;
1471  if ( mFogArray.mEnabled || enabled )
1472  {
1473  if (enabled)
1474  {
1475  if ( use_bo && vas->fogCoordArray()->bufferObject()->handle() )
1476  {
1477  buf_obj = vas->fogCoordArray()->bufferObject()->handle();
1478  ptr = 0;
1479  }
1480  else
1481  {
1482  buf_obj = 0;
1483  ptr = vas->fogCoordArray()->bufferObject()->ptr();
1484  }
1485  if ( mFogArray.mPtr != ptr || mFogArray.mBufferObject != buf_obj )
1486  {
1487  if (!mFogArray.mEnabled)
1488  {
1489  glEnableClientState(GL_FOG_COORD_ARRAY); VL_CHECK_OGL();
1490  }
1491  VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
1492  glFogCoordPointer(vas->fogCoordArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
1493  mFogArray.mPtr = ptr;
1494  mFogArray.mBufferObject = buf_obj;
1495  }
1496  }
1497  else
1498  {
1499  glDisableClientState(GL_FOG_COORD_ARRAY); VL_CHECK_OGL();
1500  mFogArray.mPtr = 0;
1501  mFogArray.mBufferObject = 0;
1502  }
1503  mFogArray.mEnabled = enabled;
1504  }
1505 
1506  // ----- texture coords -----
1507 
1508  for(int tex_coord_i=0; tex_coord_i<textureCoordCount(); ++tex_coord_i)
1509  {
1510  // texture array info
1511  const ArrayAbstract* texarr = vas->texCoordArray(tex_coord_i);
1512 
1513  if ( ! texarr ) {
1514  if ( mTexCoordArray[tex_coord_i].mEnabled ) {
1515  VL_glClientActiveTexture(GL_TEXTURE0 + tex_coord_i); VL_CHECK_OGL();
1516  glDisableClientState(GL_TEXTURE_COORD_ARRAY); VL_CHECK_OGL();
1517  mTexCoordArray[tex_coord_i].mEnabled = false;
1518  mTexCoordArray[tex_coord_i].mPtr = 0;
1519  mTexCoordArray[tex_coord_i].mBufferObject = 0;
1520  }
1521  } else {
1522  if ( ! mTexCoordArray[tex_coord_i].mEnabled ) {
1523  VL_glClientActiveTexture(GL_TEXTURE0 + tex_coord_i); VL_CHECK_OGL();
1524  glEnableClientState(GL_TEXTURE_COORD_ARRAY); VL_CHECK_OGL();
1525  mTexCoordArray[tex_coord_i].mEnabled = 1;
1526  }
1527 
1528  if ( use_bo && texarr->bufferObject()->handle() )
1529  {
1530  buf_obj = texarr->bufferObject()->handle();
1531  ptr = 0;
1532  }
1533  else
1534  {
1535  buf_obj = 0;
1536  ptr = texarr->bufferObject()->ptr();
1537  }
1538  if ( mTexCoordArray[tex_coord_i].mPtr != ptr || mTexCoordArray[tex_coord_i].mBufferObject != buf_obj )
1539  {
1540  mTexCoordArray[tex_coord_i].mPtr = ptr;
1541  mTexCoordArray[tex_coord_i].mBufferObject = buf_obj;
1542 
1543  VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
1544  glTexCoordPointer((int)texarr->glSize(), texarr->glType(), 0/*texarr->stride()*/, ptr/*+ texarr->offset()*/); VL_CHECK_OGL();
1545  }
1546  }
1547  }
1548 }
1549 //-----------------------------------------------------------------------------
1550 void OpenGLContext::bindVAS_Attribs(const IVertexAttribSet* vas, bool use_bo) {
1551  int buf_obj = 0;
1552  const unsigned char* ptr = 0;
1553 
1554  for(int idx=0; idx<vertexAttribCount(); ++idx)
1555  {
1556  const ArrayAbstract* arr = vas->vertexAttribArray(idx);
1557 
1558  if ( ! arr )
1559  {
1560  // --- disable ---
1561 
1562  if ( mVertexAttrib[idx].mEnabled ) {
1563  VL_glDisableVertexAttribArray( idx ); VL_CHECK_OGL();
1564  mVertexAttrib[idx].mEnabled = false;
1565  mVertexAttrib[idx].mPtr = 0;
1566  mVertexAttrib[idx].mBufferObject = 0;
1567  // restore constant vertex attrib
1568  glVertexAttrib4fv( idx, mVertexAttribValue[idx].ptr() ); VL_CHECK_OGL();
1569  }
1570  // make sure it's disabled
1571  #if !defined(NDEBUG)
1572  GLint enabled = 0;
1573  glGetVertexAttribiv( idx, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled); VL_CHECK(!enabled);
1574  #endif
1575  }
1576  else
1577  {
1578  // --- enable ---
1579 
1580  if ( ! mVertexAttrib[idx].mEnabled ) {
1581  VL_glEnableVertexAttribArray( idx ); VL_CHECK_OGL();
1582  mVertexAttrib[idx].mEnabled = true;
1583  }
1584  // make sure it's enabled
1585  #if !defined(NDEBUG)
1586  GLint enabled = 0;
1587  glGetVertexAttribiv( idx, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled); VL_CHECK(enabled);
1588  #endif
1589 
1590  if ( use_bo && arr->bufferObject()->handle() )
1591  {
1592  buf_obj = arr->bufferObject()->handle();
1593  ptr = 0;
1594  }
1595  else
1596  {
1597  buf_obj = 0;
1598  ptr = arr->bufferObject()->ptr();
1599  }
1600  if ( mVertexAttrib[idx].mPtr != ptr || mVertexAttrib[idx].mBufferObject != buf_obj )
1601  {
1602  mVertexAttrib[idx].mPtr = ptr;
1603  mVertexAttrib[idx].mBufferObject = buf_obj;
1604  VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
1605 
1606  if ( arr->interpretation() == VAI_NORMAL )
1607  {
1608  VL_glVertexAttribPointer( idx, (int)arr->glSize(), arr->glType(), arr->normalize(), /*stride*/0, ptr ); VL_CHECK_OGL();
1609  }
1610  else
1611  if ( arr->interpretation() == VAI_INTEGER )
1612  {
1613  VL_glVertexAttribIPointer( idx, (int)arr->glSize(), arr->glType(), /*stride*/0, ptr ); VL_CHECK_OGL();
1614  }
1615  else
1616  if ( arr->interpretation() == VAI_DOUBLE )
1617  {
1618  VL_glVertexAttribLPointer( idx, (int)arr->glSize(), arr->glType(), /*stride*/0, ptr ); VL_CHECK_OGL();
1619  }
1620  }
1621  }
1622  }
1623 }
1624 //-----------------------------------------------------------------------------
1626 {
1627  mCurVAS = NULL;
1628  mGLSLUpdated = true;
1629 
1630  for(int i=0; i<mVertexAttribCount; ++i) {
1631  VL_glDisableVertexAttribArray(i); VL_CHECK_OGL();
1632  }
1633 
1634  for(int i=0; i<vertexAttribCount(); ++i)
1635  {
1636  mVertexAttrib[i].mEnabled = false;
1637  mVertexAttrib[i].mPtr = 0;
1638  mVertexAttrib[i].mBufferObject = 0;
1639  }
1640 
1641  for(int i=0; i<textureCoordCount(); ++i)
1642  {
1643  mTexCoordArray[i].mEnabled = false;
1644  mTexCoordArray[i].mPtr = 0;
1645  mTexCoordArray[i].mBufferObject = 0;
1646  }
1647 
1648  mVertexArray.mEnabled = false;
1649  mVertexArray.mPtr = 0;
1650  mVertexArray.mBufferObject = 0;
1651 
1652  mNormalArray.mEnabled = false;
1653  mNormalArray.mPtr = 0;
1654  mNormalArray.mBufferObject = 0;
1655 
1656  mColorArray.mEnabled = false;
1657  mColorArray.mPtr = 0;
1658  mColorArray.mBufferObject = 0;
1659 
1660  mSecondaryColorArray.mEnabled = false;
1661  mSecondaryColorArray.mPtr = 0;
1662  mSecondaryColorArray.mBufferObject = 0;
1663 
1664  mFogArray.mEnabled = false;
1665  mFogArray.mPtr = 0;
1666  mFogArray.mBufferObject = 0;
1667 
1668  // reset all gl states
1669 
1670  // note this one
1671  VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); VL_CHECK_OGL();
1672 
1673  VL_glBindBuffer(GL_ARRAY_BUFFER, 0); VL_CHECK_OGL();
1674 
1676  {
1677  // iterate backwards so the last active is #0
1678  for ( int i=mTextureCoordCount; i--; )
1679  {
1680  VL_glClientActiveTexture(GL_TEXTURE0 + i); VL_CHECK_OGL();
1681  glDisableClientState(GL_TEXTURE_COORD_ARRAY); VL_CHECK_OGL();
1682  }
1683 
1684  glDisableClientState(GL_VERTEX_ARRAY); VL_CHECK_OGL();
1685  glDisableClientState(GL_NORMAL_ARRAY); VL_CHECK_OGL();
1686  glDisableClientState(GL_COLOR_ARRAY); VL_CHECK_OGL();
1687 
1688  glDisableClientState(GL_SECONDARY_COLOR_ARRAY); VL_CHECK_OGL();
1689  glDisableClientState(GL_FOG_COORD_ARRAY); VL_CHECK_OGL();
1690  }
1691 }
1692 //-----------------------------------------------------------------------------
1693 void OpenGLContext::bindVAS(const IVertexAttribSet* vas, bool use_bo, bool force)
1694 {
1695  VL_CHECK_OGL();
1696 
1697  // bring opengl to a known state
1698 
1699  if ( vas != mCurVAS || mGLSLUpdated || force )
1700  {
1701  // reset all to default/disabled state
1702 
1703  if ( ! vas || force )
1704  {
1705  bindVAS_Reset();
1706  }
1707 
1708  if (vas)
1709  {
1710  if ( mGLSLProgram && mGLSLProgram->vl_VertexPosition() != -1 ) {
1711  // disable fixed function arrays if enabled
1712  if ( mVertexArray.mEnabled ) {
1713  bindVAS_Reset();
1714  }
1715  bindVAS_Attribs( vas, use_bo );
1716  } else
1718  {
1719  // disable generic vertex attrib arrays if enabled
1720  if ( mVertexAttrib[VA_Position].mEnabled ) {
1721  bindVAS_Reset();
1722  }
1723  bindVAS_Fixed( vas, use_bo );
1724  } else {
1725  // one of the two must be present!
1726  VL_TRAP()
1727  }
1728 
1729  // ----- end -----
1730 
1731  // Note: we don't call "glBindBuffer(GL_ARRAY_BUFFER, 0)" here as it will be called by Renderer::render() just before exiting.
1732  // VL_glBindBuffer(GL_ARRAY_BUFFER, 0); VL_CHECK_OGL();
1733 
1734  } // if(vas)
1735 
1736  } // if(vas != mCurVAS || force)
1737 
1738  mCurVAS = vas;
1739  mGLSLUpdated = false;
1740 
1741  VL_CHECK_OGL();
1742 }
1743 //-----------------------------------------------------------------------------
1745 {
1746  mGLSLUpdated = true;
1747 
1748  if ( glsl )
1749  {
1750  VL_CHECK_OGL();
1751  VL_CHECK( Has_GLSL );
1752  bool ok = Has_GLSL;
1753 
1754  // This if is necessary to distinguish the default GLSLProgram which has no shaders.
1755  if ( glsl->shaderCount() ) {
1756  if ( ! glsl->handle() )
1757  {
1758  Log::bug("GLSLProgram::useProgram() failed! GLSL program handle is null! (" + String(objectName()) + ")\n");
1759  // VL_TRAP()
1760  ok = false;
1761  }
1762 
1763  if ( ! glsl->linked() )
1764  {
1765  Log::bug("GLSLProgram::useProgram() failed! GLSL program not linked! (" + String(objectName()) + ")\n");
1766  // VL_TRAP()
1767  ok = false;
1768  }
1769  }
1770 
1771  // bind the GLSL program
1772  if ( ok )
1773  {
1774  glUseProgram( glsl->handle() ); VL_CHECK_OGL()
1775  mGLSLProgram = glsl;
1776  }
1777  else
1778  {
1779  glUseProgram( 0 ); VL_CHECK_OGL()
1780  mGLSLProgram = NULL;
1781  }
1782  }
1783  else
1784  {
1785  glUseProgram( 0 ); VL_CHECK_OGL();
1786  mGLSLProgram = NULL;
1787  }
1788 }
1789 //-----------------------------------------------------------------------------
static void debug(const String &message)
Use this function to provide extra information useful to investigate and solve problems.
Definition: Log.cpp:145
virtual const ArrayAbstract * vertexArray() const =0
Conventional vertex array.
The ArrayAbstract class defines an abstract interface to conveniently manipulate data stored in a Buf...
Definition: Array.hpp:58
bool Has_GLES_Version_1_1
Definition: OpenGL.cpp:67
virtual void addedListenerEvent(OpenGLContext *)=0
Event generated whenever a listener is bound to an OpenGLContext context.
bool Has_GL_Version_1_4
Definition: OpenGL.cpp:52
RenderState wrapping the OpenGL function glPointParameter(), see also http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml for more information.
Definition: Shader.hpp:1221
RenderState wrapping the OpenGL function glStencilOp() and glStencilOpSeparate(), see also http://www...
Definition: Shader.hpp:1346
Abstract interface to manipulate OpenGL&#39;s vertex attribute arrays.
virtual const ArrayAbstract * normalArray() const =0
Conventional normal array.
Vector3< float > fvec3
A 3 components vector with float precision.
Definition: Vector3.hpp:252
bool Has_Cubemap_Textures
Definition: OpenGL.cpp:86
void setVSyncEnabled(bool enable)
If the OpenGL context is a widget this function enabled/disables double buffer swapping to the monito...
void resetContextStates(EResetContextStates start_or_finish)
Resets the OpenGL states necessary to begin and finish a rendering. - For internal use only...
const GLenum Translate_Enable[]
Definition: OpenGL.cpp:128
bool Has_Texture_Multisample
Definition: OpenGL.cpp:90
bool Has_GL_Version_4_1
Definition: OpenGL.cpp:61
bool Has_GL_Version_1_1
Definition: OpenGL.cpp:49
RenderState wrapping the OpenGL function glDepthFunc(), see also http://www.opengl.org/sdk/docs/man/xhtml/glDepthFunc.xml for more information.
Definition: Shader.hpp:461
size_t renderStatesCount() const
RenderState wrapping the OpenGL function glHint(), see also http://www.opengl.org/sdk/docs/man/xhtml/...
Definition: Shader.hpp:346
Vector4< float > fvec4
A 4 components vector with float precision.
Definition: Vector4.hpp:279
bool Has_Multitexture
Definition: OpenGL.cpp:92
The UIEventListener class listens to the events emitted by an OpenGLContext.
A simple String formatting class.
Definition: Say.hpp:124
const char * Translate_Enable_String[]
Definition: OpenGL.cpp:185
RenderState wrapping the OpenGL function glPolygonOffset(), see also http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml for more information.
Definition: Shader.hpp:963
RenderState wrapping the OpenGL function glPolygonMode(), see also http://www.opengl.org/sdk/docs/man/xhtml/glPolygonMode.xml for more information.
Definition: Shader.hpp:527
static void warning(const String &message)
Use this function to provide information about situations that might lead to errors or loss of data...
Definition: Log.cpp:155
bool Has_GL_Version_2_1
Definition: OpenGL.cpp:55
VLGRAPHICS_EXPORT void * getGLProcAddress(const char *name)
Returns the address of the specified OpenGL function if supported by the active OpenGL driver and pro...
Definition: OpenGL.cpp:719
void applyEnables(const EnableSet *cur)
Applies an EnableSet to an OpenGLContext - Typically for internal use only.
RenderState wrapping the OpenGL function glNormal(), see also http://www.opengl.org/sdk/docs/man/xhtm...
Definition: Shader.hpp:162
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
RenderState wrapping the OpenGL function glLogicOp(), see also http://www.opengl.org/sdk/docs/man/xht...
Definition: Shader.hpp:1005
void eraseAllEventListeners()
Removes all UIEventListener previously registered.
virtual const ArrayAbstract * texCoordArray(int tex_unit) const =0
Conventional texture coords arrays.
Data will be sent using glVertexAttribIPointer(), that is, values are always left as integer values...
RenderState wrapping the OpenGL function glLightModel(), see also http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml for more information.
Definition: Shader.hpp:859
RenderState wrapping the OpenGL function glBlendFunc(), see also http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunc.xml for more information.
Definition: Shader.hpp:600
bool linked() const
Returns true if the program has been succesfully linked.
Definition: GLSL.hpp:288
void logOpenGLInfo()
Logs some information about the OpenGL context.
Represents an OpenGL context, possibly a widget or a pbuffer, which can also respond to keyboard...
RenderState wrapping the OpenGL function glPolygonStipple(), see also http://www.opengl.org/sdk/docs/man/xhtml/glPolygonStipple.xml for more information.
Definition: Shader.hpp:1149
If enabled, dither color components or indices before they are written to the color buffer...
RenderState wrapping the OpenGL function glFrontFace(), see also http://www.opengl.org/sdk/docs/man/xhtml/glFrontFace.xml for more information.
Definition: Shader.hpp:428
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
RenderState wrapping the OpenGL function glShadeModel(), see also http://www.opengl.org/sdk/docs/man/xhtml/glShadeModel.xml for more information.
Definition: Shader.hpp:567
void bindVAS_Fixed(const IVertexAttribSet *vas, bool use_vbo)
void resetEnables()
Resets all the interanal enable-tables - For internal use only.
void * getProcAddress(const char *function_name)
Returns the address of an OpenGL extension function.
virtual size_t glSize() const =0
Returns the number of scalar components for the array, ie 3 for ArrayFloat3, 1 for ArrayUInt1 etc...
Wraps a GLSL program to which you can bind vertex, fragment and geometry shaders. ...
Definition: GLSL.hpp:233
bool Has_Texture_Rectangle
Definition: OpenGL.cpp:87
void addEventListener(UIEventListener *el)
Adds an UIEventListener to be notified of OpenGLContext related events.
RenderState wrapping the OpenGL function glDepthMask(), see also http://www.opengl.org/sdk/docs/man/xhtml/glDepthMask.xml for more information.
Definition: Shader.hpp:494
bool Has_GL_Version_4_0
Definition: OpenGL.cpp:60
bool Is_OpenGL_Core_Profile
OpenGL: true if the current context has been created with the WGL_CONTEXT_CORE_PROFILE_BIT_ARB or equ...
Definition: OpenGL.cpp:46
EVertexAttribInterpretation interpretation() const
How the data is interpreted by the OpenGL, see EVertexAttribInterpretation.
Definition: Array.hpp:182
const std::vector< ref< Uniform > > & uniforms() const
Definition: UniformSet.hpp:68
EResetContextStates
void destroyAllFramebufferObjects()
Removes all FramebufferObjects belonging to an OpenGLContext.
RenderState wrapping the OpenGL function glPixelTransfer(), see also http://www.opengl.org/sdk/docs/man/xhtml/glPixelTransfer.xml for more information.
Definition: Shader.hpp:196
bool Has_GL_Version_3_0
Definition: OpenGL.cpp:56
T log(T a)
Definition: glsl_math.hpp:486
bool vsyncEnabled() const
If the OpenGL context is a widget this function returns whether vsync is enabled or not...
RenderState wrapping the OpenGL function glColor(), see also http://www.opengl.org/sdk/docs/man/xhtml...
Definition: Shader.hpp:94
The TextureMatrix class uses a 4x4 matrix to transform the texture coordinates of a texture unit...
Definition: Shader.hpp:1539
RenderState wrapping the OpenGL function glDepthRange(), see also http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml for more information.
Definition: Shader.hpp:1038
EReadDrawBuffer
Visualization Library main namespace.
const BufferObject * bufferObject() const
Definition: Array.hpp:97
bool Has_GLSL
Definition: OpenGL.cpp:73
void bindVAS_Attribs(const IVertexAttribSet *vas, bool use_vbo)
virtual void normalize()=0
Normalizes the vectors contained in the buffer.
OpenGLContext(int w=0, int h=0)
Constructor.
RenderState wrapping the OpenGL function glTexEnv(), see also http://www.opengl.org/sdk/docs/man/xhtm...
Definition: Shader.hpp:1589
RenderState wrapping the OpenGL function glBlendColor(), see also http://www.opengl.org/sdk/docs/man/xhtml/glBlendColor.xml for more information.
Definition: Shader.hpp:1455
bool Has_BufferObject
Definition: OpenGL.cpp:82
virtual const ArrayAbstract * secondaryColorArray() const =0
Conventional secondary color array.
RenderState wrapping the OpenGL function glLineStipple(), see also http://www.opengl.org/sdk/docs/man/xhtml/glLineStipple.xml for more information.
Definition: Shader.hpp:1181
bool Has_GLES_Version_2_0
Definition: OpenGL.cpp:68
bool Has_Texture_Array
Definition: OpenGL.cpp:88
static void bug(const String &message)
Use this function to provide information about programming errors: wrong parameter initialization...
Definition: Log.cpp:175
bool Has_Transform_Feedback
Definition: OpenGL.cpp:95
For internal use only.
#define VL_TRAP()
Definition: checks.hpp:70
Wraps the OpenGL function glClipPlane().
Definition: ClipPlane.hpp:49
bool Has_GL_Version_1_3
Definition: OpenGL.cpp:51
void useGLSLProgram(const GLSLProgram *glsl)
Activates the given GLSLProgram or unbinds the current one if glsl is NULL.
virtual const ArrayAbstract * vertexAttribArray(int attrib_location) const =0
Returns a generic vertex attribute&#39;s info.
RenderState wrapping the OpenGL function glColorMask(), see also http://www.opengl.org/sdk/docs/man/xhtml/glColorMask.xml for more information.
Definition: Shader.hpp:1488
Data will be sent using glVertexAttribLPointer(), that is, it will be associated with a shader attrib...
virtual void removedListenerEvent(OpenGLContext *)=0
Event generated whenever a listener is unbound from an OpenGLContext context.
VLGRAPHICS_EXPORT bool initializeOpenGL()
To test whether OpenGL has been initialized at least once check vl::Is_OpenGL_Initialized.
Definition: OpenGL.cpp:304
virtual const ArrayAbstract * fogCoordArray() const =0
Conventional fog array.
The TextureSampler class associates a Texture object to an OpenGL texture unit.
Definition: Shader.hpp:1747
void destroyAllOpenGLResources()
Removes all OpenGL resources handled by the OpenGLContext.
bool isExtensionSupported(const char *ext_name)
Returns true if the given extension is supported.
bool empty() const
Returns true if length() == 0.
Definition: String.hpp:136
virtual void apply(const Camera *camera, OpenGLContext *ctx) const
RenderState wrapping the OpenGL function glTexGen(), see also http://www.opengl.org/sdk/docs/man/xhtm...
Definition: Shader.hpp:1682
RenderState wrapping the OpenGL function glLineWidth(), see also http://www.opengl.org/sdk/docs/man/xhtml/glLineWidth.xml for more information.
Definition: Shader.hpp:1083
bool Has_GLES
Definition: OpenGL.cpp:69
~OpenGLContext()
Destructor.
Wraps the OpenGL functions glStencilFunc() and glStencilFuncSeparate(), see also http://www.opengl.org/sdk/docs/man/xhtml/glStencilFunc.xml and http://www.opengl.org/sdk/docs/man/xhtml/glStencilFuncSeparate.xml for more information.
Definition: Shader.hpp:1279
virtual void initEvent()=0
Event generated when the bound OpenGLContext bocomes initialized or when the event listener is bound ...
void applyRenderStates(const RenderStateSet *cur, const Camera *camera)
Applies a RenderStateSet to an OpenGLContext - Typically for internal use only.
#define NULL
Definition: OpenGLDefs.hpp:81
Data will be sent using glVertexAttribPointer(), that is, data will be converted to floating point pr...
RenderState wrapping the OpenGL function glBlendEquation()/glBlendEquationSeparate(), see also http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquation.xml and http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml for more information.
Definition: Shader.hpp:657
A set of RenderState objects managed by a Shader.
RenderState wrapping the OpenGL function glMaterial() and glColorMaterial(), see also http://www...
Definition: Shader.hpp:774
void destroyFramebufferObject(FramebufferObject *fbort)
Destroys the specified FramebufferObject.
bool Has_Texture_Buffer
Definition: OpenGL.cpp:89
void bindVAS(const IVertexAttribSet *vas, bool use_vbo, bool force)
Activates the specified vertex attribute set - For internal use only.
bool isCleanState(bool verbose)
Checks whether the OpenGL state is clean or not.
EEnable
Constant that enable/disable a specific OpenGL feature, see also Shader, Shader::enable(), Shader::disable(), Shader::isEnabled()
virtual GLenum glType() const =0
Returns the OpenGL type for the array, ie GL_FLOAT for ArrayFloat3, GL_UNSIGNED_INT for ArrayUInt1 et...
RenderState wrapping the OpenGL function glPointSize(), see also http://www.opengl.org/sdk/docs/man/xhtml/glPointSize.xml for more information.
Definition: Shader.hpp:1116
#define VL_CHECK_OGL()
Definition: OpenGL.hpp:156
unsigned int handle() const
const std::string & objectName() const
The name of the object, by default set to the object&#39;s class name.
Definition: Object.hpp:217
Implements a framebuffer object to be used as a rendering target as specified by the ARB_framebuffer_...
If enabled, use multiple fragment samples in computing the final color of a pixel.
ref< FramebufferObject > createFramebufferObject()
Equivalent to "createFramebufferObject(0,0);".
unsigned char * ptr()
Definition: Buffer.hpp:201
RenderState wrapping the OpenGL function glAlphaFunc(), see also http://www.opengl.org/sdk/docs/man/xhtml/glAlphaFunc.xml for more information.
Definition: Shader.hpp:737
bool Has_GL_Version_2_0
Definition: OpenGL.cpp:54
ERenderState type() const
Wraps the OpenGL function glLight().
Definition: Light.hpp:51
A set of Uniform objects managed by a Shader.
Definition: UniformSet.hpp:50
bool Has_Fixed_Function_Pipeline
OpenGL: true if !Is_OpenGL_Forward_Compatible && !Is_OpenGL_Core_Profile OpenGL ES 1: always true Ope...
Definition: OpenGL.cpp:63
bool Has_Primitive_Restart
Definition: OpenGL.cpp:93
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
OpenGLContext * openglContext()
Returns the OpenGLContext to which this UIEventListener is bound or NULL if no context is bound...
void resetRenderStates()
Resets all the interanal render-states-tables - For internal use only.
virtual void setEnabled(bool enabled)
Enables or disables a UIEventListener.
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:50
bool Is_Enable_Supported[EN_EnableCount]
Definition: OpenGL.cpp:242
void removeEventListener(UIEventListener *el)
Removes an UIEventListener.
unsigned int handle() const
The handle of the GLSL program as returned by glCreateProgram()
Definition: GLSL.hpp:273
bool Has_PBO
Definition: OpenGL.cpp:84
bool Has_GL_Version_1_2
Definition: OpenGL.cpp:50
bool Has_FBO
Definition: OpenGL.cpp:83
RenderState wrapping the OpenGL function glStencilMask() and glStencilMaskSeparate(), see also http://www.opengl.org/sdk/docs/man/xhtml/glStencilMask.xml and http://www.opengl.org/sdk/docs/man/xhtml/glStencilMaskSeparate.xml for more information.
Definition: Shader.hpp:1413
const RenderStateSlot * renderStates() const
bool initGLContext(bool log=true)
Initializes the supported OpenGL extensions.
int shaderCount() const
Returns the number of GLSLShader objects bound to this GLSLProgram.
Definition: GLSL.hpp:334
#define VL_CHECK(expr)
Definition: checks.hpp:73
The Framebuffer class defines an abstract &#39;surface&#39; where OpenGL can render into. ...
Definition: Framebuffer.hpp:49
bool Has_Texture_3D
Definition: OpenGL.cpp:91
ref< RenderState > mRS
static bool areUniformsColliding(const UniformSet *u1, const UniformSet *u2)
Returns true if the two UniformSet contain at least one Uniform variable with the same name...
VLCORE_EXPORT GlobalSettings * globalSettings()
Returns VisulizationLibrary&#39;s global settings.
Definition: pimpl.cpp:52
RenderState wrapping the OpenGL function glFog(), see also http://www.opengl.org/sdk/docs/man/xhtml/g...
Definition: Shader.hpp:907
RenderState wrapping the OpenGL function glSecondaryColor(), see also http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml for more information.
Definition: Shader.hpp:128
virtual const ArrayAbstract * colorArray() const =0
Conventional color array.
A set of enables managed by Shader.
Definition: EnableSet.hpp:47
const std::vector< EEnable > & enables() const
Definition: EnableSet.hpp:89
RenderState wrapping the OpenGL function glSampleCoverage(), see also http://www.opengl.org/sdk/docs/man/xhtml/glSampleCoverage.xml for more information.
Definition: Shader.hpp:697
RenderState wrapping the OpenGL function glCullFace(), see also http://www.opengl.org/sdk/docs/man/xhtml/glCullFace.xml for more information.
Definition: Shader.hpp:395