Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/OpenGLContext.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2011, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlCore/GlobalSettings.hpp>
00033 #include <vlGraphics/OpenGLContext.hpp>
00034 #include <vlGraphics/OpenGL.hpp>
00035 #include <vlGraphics/IVertexAttribSet.hpp>
00036 #include <vlGraphics/Shader.hpp>
00037 #include <vlGraphics/GLSL.hpp>
00038 #include <vlGraphics/Light.hpp>
00039 #include <vlGraphics/ClipPlane.hpp>
00040 #include <vlCore/Log.hpp>
00041 #include <vlCore/Say.hpp>
00042 #include <algorithm>
00043 #include <sstream>
00044 #include <vlGraphics/NaryQuickMap.hpp>
00045 
00046 using namespace vl;
00047 
00048 //-----------------------------------------------------------------------------
00049 // UIEventListener
00050 //-----------------------------------------------------------------------------
00051 OpenGLContext* UIEventListener::openglContext() { return mOpenGLContext; }
00052 //-----------------------------------------------------------------------------
00053 // OpenGLContext
00054 //-----------------------------------------------------------------------------
00055 OpenGLContext::OpenGLContext(int w, int h)
00056 {
00057   VL_DEBUG_SET_OBJECT_NAME()
00058   mLeftFramebuffer  = new Framebuffer(this, w, h, RDB_BACK_LEFT, RDB_BACK_LEFT);
00059   mRightFramebuffer = new Framebuffer(this, w, h, RDB_BACK_RIGHT, RDB_BACK_RIGHT);
00060 
00061   // set to unknown texture target
00062   memset( mTexUnitBinding, 0, sizeof(mTexUnitBinding) );
00063 
00064   mCurrentEnableSet = new NaryQuickMap<EEnable, EEnable, EN_EnableCount>;
00065   mNewEnableSet = new NaryQuickMap<EEnable, EEnable, EN_EnableCount>;
00066 
00067   mCurrentRenderStateSet = new NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount>;
00068   mNewRenderStateSet = new NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount>;
00069 
00070   mIsInitialized = false;
00071   mHasDoubleBuffer = false;
00072   mMaxVertexAttrib = 0;
00073   mTextureSamplerCount = 0;
00074   mCurVAS = NULL;
00075 
00076   mNormal = fvec3(0,1,0);
00077   mColor  = fvec4(1,1,1,1);
00078   mSecondaryColor = fvec3(1,1,1);
00079 
00080   // --- GUI ---
00081 
00082   mMouseVisible = true;
00083   mContinuousUpdate = true;
00084   mIgnoreNextMouseMoveEvent = false;
00085   mFullscreen = false;
00086 }
00087 //-----------------------------------------------------------------------------
00088 OpenGLContext::~OpenGLContext()
00089 {
00090   if (mFramebufferObject.size() || mEventListeners.size())
00091     Log::warning("~OpenGLContext(): you should have called dispatchDestroyEvent() before destroying the OpenGLContext!\nNow it's too late to cleanup things!\n");
00092 
00093   // invalidate the left and right framebuffers
00094   mLeftFramebuffer->mOpenGLContext = NULL;
00095   mRightFramebuffer->mOpenGLContext = NULL;
00096 
00097   // invalidate FBOs
00098   for(unsigned i=0; i<mFramebufferObject.size(); ++i)
00099   {
00100     // note, we can't destroy the FBOs here because it's too late to call makeCurrent().
00101     // mFramebufferObject[i]->destroy();
00102     mFramebufferObject[i]->mOpenGLContext = NULL;
00103   }
00104 
00105   // remove all the event listeners
00106   eraseAllEventListeners();
00107 }
00108 //-----------------------------------------------------------------------------
00109 ref<FramebufferObject> OpenGLContext::createFramebufferObject(int width, int height, EReadDrawBuffer draw_buffer, EReadDrawBuffer read_buffer)
00110 {
00111   makeCurrent();
00112   mFramebufferObject.push_back(new FramebufferObject(this, width, height, draw_buffer, read_buffer));
00113   mFramebufferObject.back()->createFBO();
00114   return mFramebufferObject.back();
00115 }
00116 //-----------------------------------------------------------------------------
00117 void OpenGLContext::destroyFramebufferObject(FramebufferObject* fbort)
00118 {
00119   makeCurrent();
00120   for(unsigned i=0; i<mFramebufferObject.size(); ++i)
00121   {
00122     if (mFramebufferObject[i] == fbort)
00123     {
00124       mFramebufferObject[i]->deleteFBO();
00125       mFramebufferObject[i]->mOpenGLContext = NULL;
00126       mFramebufferObject.erase(mFramebufferObject.begin()+i);
00127       return;
00128     }
00129   }
00130 }
00131 //-----------------------------------------------------------------------------
00132 void OpenGLContext::destroyAllFramebufferObjects()
00133 {
00134   makeCurrent();
00135   for(unsigned i=0; i<mFramebufferObject.size(); ++i)
00136   {
00137     mFramebufferObject[i]->deleteFBO();
00138     mFramebufferObject[i]->mOpenGLContext = NULL;
00139   }
00140   mFramebufferObject.clear();
00141 }
00142 //-----------------------------------------------------------------------------
00143 void OpenGLContext::addEventListener(UIEventListener* el)
00144 {
00145   VL_CHECK( el );
00146   VL_CHECK( el->mOpenGLContext == NULL );
00147   if (el->mOpenGLContext == NULL)
00148   {
00149     mEventListeners.push_back(el);
00150     el->mOpenGLContext = this;
00151     el->addedListenerEvent(this);
00152     if (isInitialized())
00153       el->initEvent();
00154   }
00155 }
00156 //-----------------------------------------------------------------------------
00157 void OpenGLContext::removeEventListener(UIEventListener* el)
00158 {
00159   VL_CHECK( el );
00160   VL_CHECK( el->mOpenGLContext == this || el->mOpenGLContext == NULL );
00161   if (el->mOpenGLContext == this)
00162   {
00163     std::vector< ref<UIEventListener> >::iterator pos = std::find(mEventListeners.begin(), mEventListeners.end(), el);
00164     if( pos != mEventListeners.end() )
00165     {
00166       mEventListeners.erase( pos );
00167       // any operation here is safe, even adding or removing listeners.
00168       el->removedListenerEvent(this);
00169       el->mOpenGLContext = NULL;
00170     }
00171   }
00172 }
00173 //-----------------------------------------------------------------------------
00174 void OpenGLContext::eraseAllEventListeners()
00175 {
00176   // iterate on a temp vector so that any operations inside removedListenerEvent() is safe,
00177   // even adding or removing listeners.
00178   std::vector< ref<UIEventListener> > temp = mEventListeners;
00179   mEventListeners.clear();
00180   for(size_t i=0; i<temp.size(); ++i)
00181   {
00182     VL_CHECK( temp[i]->mOpenGLContext == this );
00183     temp[i]->removedListenerEvent(this);
00184     temp[i]->mOpenGLContext = NULL;
00185   }
00186 }
00187 //-----------------------------------------------------------------------------
00188 void OpenGLContext::setVSyncEnabled(bool enable)
00189 {
00190 #if defined(VL_OPENGL) && defined(VL_PLATFORM_WINDOWS)
00191   makeCurrent();
00192   if (Has_GL_EXT_swap_control)
00193     wglSwapIntervalEXT(enable?1:0);
00194 #else
00195   // Mac and Linux?
00196 #endif
00197 }
00198 //-----------------------------------------------------------------------------
00199 bool OpenGLContext::vsyncEnabled() const
00200 {
00201 #if defined(VL_OPENGL) && defined(VL_PLATFORM_WINDOWS)
00202   if (Has_GL_EXT_swap_control)
00203     return wglGetSwapIntervalEXT() != 0;
00204   else
00205     return false;
00206 #else
00207   return false;
00208 #endif
00209 }
00210 //-----------------------------------------------------------------------------
00211 bool OpenGLContext::initGLContext(bool log)
00212 {
00213   mIsInitialized = false;
00214 
00215   makeCurrent();
00216 
00217   // init OpenGL extensions
00218   if (!initializeOpenGL())
00219   {
00220     Log::error("Error initializing OpenGL!\n");
00221     VL_TRAP()
00222     return false;
00223   }
00224 
00225   mExtensions = getOpenGLExtensions();
00226 
00227   if (log)
00228     logOpenGLInfo();
00229 
00230   VL_CHECK_OGL();
00231 
00232   // Find max number of texture units, see http://www.opengl.org/sdk/docs/man/xhtml/glActiveTexture.xml
00233   mTextureSamplerCount = 1;
00234   if (Has_GL_ARB_multitexture||Has_GL_Version_1_3||Has_GLES_Version_1_1) // for GL < 2.x
00235   {
00236     int max_tmp = 0;
00237     glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
00238     mTextureSamplerCount = max_tmp > mTextureSamplerCount ? max_tmp : mTextureSamplerCount;
00239   }
00240   if (Has_GL_Version_2_0) // for GL == 2.x
00241   {
00242     int max_tmp = 0;
00243     glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
00244     mTextureSamplerCount = max_tmp > mTextureSamplerCount ? max_tmp : mTextureSamplerCount;
00245   }
00246   if (Has_GLSL) // for GL >= 2.0
00247   {
00248     int max_tmp = 0;
00249     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_tmp); VL_CHECK_OGL();
00250     mTextureSamplerCount = max_tmp > mTextureSamplerCount ? max_tmp : mTextureSamplerCount;
00251   }
00252   mTextureSamplerCount = mTextureSamplerCount < VL_MAX_TEXTURE_UNITS ? mTextureSamplerCount : VL_MAX_TEXTURE_UNITS;
00253 
00254   // find max number of vertex attributes
00255   mMaxVertexAttrib = 0;
00256   if(Has_GLSL)
00257     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mMaxVertexAttrib);
00258   mMaxVertexAttrib = mMaxVertexAttrib < VL_MAX_GENERIC_VERTEX_ATTRIB ? mMaxVertexAttrib : VL_MAX_GENERIC_VERTEX_ATTRIB;
00259 
00260   VL_CHECK_OGL();
00261 
00262 #if defined(VL_OPENGL)
00263   // test for double buffer availability
00264   glDrawBuffer(GL_BACK);
00265   if ( glGetError() )
00266     mHasDoubleBuffer = false;
00267   else
00268     mHasDoubleBuffer = true;
00269 #else
00270   mHasDoubleBuffer = true;
00271 #endif
00272 
00273   setupDefaultRenderStates();
00274 
00275   return mIsInitialized = true;;
00276 }
00277 //-----------------------------------------------------------------------------
00278 bool OpenGLContext::isExtensionSupported(const char* ext_name)
00279 {
00280   makeCurrent();
00281   size_t len = strlen(ext_name);
00282   const char* ext = mExtensions.c_str();
00283   const char* ext_end = ext + strlen(ext);
00284 
00285   for( const char* pos = strstr(ext,ext_name); pos && pos < ext_end; pos = strstr(pos,ext_name) )
00286   {
00287     if (pos[len] == ' ' || pos[len] == 0)
00288       return true;
00289     else
00290       pos += len;
00291   }
00292 
00293   return false;
00294 }
00295 //-----------------------------------------------------------------------------
00296 void* OpenGLContext::getProcAddress(const char* function_name)
00297 {
00298   makeCurrent();
00299   return getGLProcAddress(function_name);
00300 }
00301 //-----------------------------------------------------------------------------
00302 void OpenGLContext::logOpenGLInfo()
00303 {
00304   makeCurrent();
00305 
00306   Log::debug(" --- OpenGL Info ---\n");
00307   Log::debug( Say("OpenGL version: %s\n") << glGetString(GL_VERSION) );
00308   Log::debug( Say("OpenGL vendor: %s\n") << glGetString(GL_VENDOR) );
00309   Log::debug( Say("OpenGL renderer: %s\n") << glGetString(GL_RENDERER) );
00310   Log::debug( Say("OpenGL profile: %s\n") << (Has_Fixed_Function_Pipeline ? "Compatible" : "Core") );
00311 
00312   if (Has_GLSL)
00313     Log::debug( Say("GLSL version: %s\n") << glGetString(GL_SHADING_LANGUAGE_VERSION) );
00314     
00315   int max_val = 0;
00316   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_val);
00317   Log::debug( Say("Max texture size: %n\n")<<max_val);
00318 
00319   max_val = 1;
00320   if (Has_GL_ARB_multitexture||Has_GL_Version_1_3||Has_GLES_Version_1_1)
00321     glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_val); // deprecated enum
00322   Log::debug( Say("Texture units (legacy): %n\n") << max_val);
00323 
00324   max_val = 0;
00325   if (Has_GL_Version_2_0)
00326   {
00327     glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_val); // deprecated enum
00328     Log::debug( Say("Texture units (client): %n\n") << max_val);
00329   }
00330   if (Has_GLSL)
00331   {
00332     int tmp = 0;
00333     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &tmp);
00334     // max between GL_MAX_TEXTURE_COORDS and GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
00335     max_val = tmp > max_val ? tmp : max_val;
00336     Log::debug( Say("Texture units (combined): %n\n") << max_val);
00337   }
00338 
00339   max_val = 0;
00340   if (Has_GLSL)
00341   {
00342     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_val);
00343     Log::debug( Say("Texture units (fragment shader): %n\n") << max_val);
00344   }
00345 
00346   max_val = 0;
00347   if (Has_GL_EXT_texture_filter_anisotropic)
00348     glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_val);
00349   Log::debug( Say("Anisotropic texture filter: %s, ") << (Has_GL_EXT_texture_filter_anisotropic? "YES" : "NO") );
00350   Has_GL_EXT_texture_filter_anisotropic ? Log::debug( Say("%nX\n") << max_val) : Log::debug("\n");
00351   Log::debug( Say("S3 Texture Compression: %s\n") << (Has_GL_EXT_texture_compression_s3tc? "YES" : "NO") );
00352   Log::debug( Say("Vertex Buffer Object: %s\n") << (Has_BufferObject? "YES" : "NO"));
00353   Log::debug( Say("Pixel Buffer Object: %s\n") << (Has_PBO ? "YES" : "NO"));
00354   Log::debug( Say("Framebuffer Object: %s\n") << (Has_FBO? "YES" : "NO"));
00355 
00356   max_val = 0;
00357   if(Has_GLSL)
00358   {
00359     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_val); VL_CHECK_OGL();
00360     Log::debug( Say("Max vertex attributes: %n\n")<<max_val);      
00361   }
00362 
00363   VL_CHECK_OGL();
00364 
00365   max_val = 0; 
00366   if(Has_GLSL)
00367   {
00368     // - opengl 3.2 seem to deprecate both  GL_MAX_VARYING_COMPONENTS and GL_MAX_VARYING_FLOATS 
00369     //   but does not support explicitly GL_MAX_VARYING_VECTORS, leving the issue ambiguous.
00370     // - my GTX 460 in opengl 3.2 core allows GL_MAX_VARYING_VECTORS
00371     // - a user reported that a Quadro FX GL 3.2 compatibility did not support GL_MAX_VARYING_VECTORS
00372     // - ergo we don't check if we are in GL 3.x non-compatible mode
00373     if (Has_GLES_Version_2_0||Has_GL_Version_4_1)
00374     {
00375       glGetIntegerv(GL_MAX_VARYING_VECTORS, &max_val); VL_CHECK_OGL();
00376     }
00377     else
00378     if (Has_GL_Version_2_0)
00379     {
00380       glGetIntegerv(GL_MAX_VARYING_FLOATS, &max_val); VL_CHECK_OGL();
00381       max_val /= 4;
00382     }
00383     Log::debug( Say("Max varying vectors: %n\n")<<max_val);
00384   }
00385 
00386   max_val = 0;
00387   if(Has_GLSL)
00388   {
00389     if (Has_GLES_Version_2_0)
00390     {
00391       glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &max_val); VL_CHECK_OGL();
00392     }
00393     else
00394     {
00395       glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max_val); VL_CHECK_OGL();
00396       max_val /= 4;
00397     }
00398       
00399     Log::debug( Say("Max fragment uniform vectors: %n\n")<<max_val);
00400   }
00401     
00402   max_val = 0;
00403   if(Has_GLSL)
00404   {
00405     if (Has_GLES_Version_2_0)
00406     {
00407       glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &max_val); VL_CHECK_OGL();
00408     }
00409     else
00410     {
00411       glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max_val); VL_CHECK_OGL();
00412       max_val /= 4;
00413     }
00414       
00415     Log::debug( Say("Max vertex uniform vectors: %n\n")<<max_val);
00416   }
00417     
00418   max_val = 0;
00419   if(Has_GL_Version_1_2||Has_GL_Version_3_0||Has_GL_Version_4_0)
00420   {
00421     glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_val); VL_CHECK_OGL();
00422     Log::debug( Say("Max elements vertices: %n\n") << max_val );
00423   }
00424 
00425   max_val = 0;
00426   if(Has_GL_Version_1_2||Has_GL_Version_3_0||Has_GL_Version_4_0)
00427   {
00428     glGetIntegerv(GL_MAX_ELEMENTS_INDICES,  &max_val ); VL_CHECK_OGL();
00429     Log::debug( Say("Max elements indices: %n\n") << max_val );
00430   }
00431 
00432   if (Has_Fixed_Function_Pipeline)
00433   {
00434     max_val = 0;
00435     glGetIntegerv(GL_MAX_CLIP_PLANES,  &max_val ); VL_CHECK_OGL();
00436     Log::debug( Say("Max clipping planes: %n\n") << max_val );
00437   }
00438   else
00439   if (Has_GLSL && !Has_GLES_Version_2_0)
00440   {
00441     max_val = 0;
00442     glGetIntegerv(GL_MAX_CLIP_DISTANCES,  &max_val ); VL_CHECK_OGL();
00443     Log::debug( Say("Max clip distances: %n\n") << max_val );
00444   }
00445 
00446   // --- log supported extensions on two columns ---
00447 
00448   Log::debug("\n --- OpenGL Extensions --- \n");
00449 
00450   std::stringstream sstream;
00451   sstream << extensions();
00452   std::string ext, line;
00453   for( int i=0; !sstream.eof(); ++i )
00454   {
00455     sstream >> ext;
00456     if (sstream.eof())
00457       break;
00458 
00459     if (i && i % 2)
00460     {
00461       line.resize(40,' ');
00462       line += ext;
00463       Log::debug( Say("%s\n") << line );
00464       line.clear();
00465     }
00466     else
00467       line = ext;
00468   }
00469   if (line.length())
00470     Log::debug( Say("%s\n") << line );
00471   Log::debug("\n");
00472 
00473   VL_CHECK_OGL();
00474 }
00475 //------------------------------------------------------------------------------
00476 void OpenGLContext::applyEnables( const EnableSet* new_enables )
00477 {
00478   VL_CHECK_OGL()
00479 
00480   mNewEnableSet->clear();
00481 
00482   if (new_enables)
00483   {
00484     for( size_t i=0; i<new_enables->enables().size(); ++i )
00485     {
00486       const EEnable& capability = new_enables->enables()[i];
00487       mNewEnableSet->append(capability);
00488       if(!mCurrentEnableSet->hasKey(capability))
00489       {
00490         glEnable( Translate_Enable[capability] );
00491         #ifndef NDEBUG
00492           if (glGetError() != GL_NO_ERROR)
00493           {
00494             Log::error( Say("An unsupported capability has been enabled: %s.\n") << Translate_Enable_String[capability]);
00495           }
00496         #endif
00497       }
00498     }
00499   }
00500 
00501   for(EEnable* capability = mCurrentEnableSet->begin(); capability != mCurrentEnableSet->end(); ++capability)
00502   {
00503     if (!mNewEnableSet->hasKey(*capability))
00504     {
00505       glDisable( Translate_Enable[*capability] );
00506       #ifndef NDEBUG
00507         if (glGetError() != GL_NO_ERROR)
00508         {
00509           Log::error( Say("An unsupported capability has been disabled: %s.\n") << Translate_Enable_String[*capability]);
00510         }
00511       #endif
00512     }
00513   }
00514 
00515   std::swap(mNewEnableSet, mCurrentEnableSet);
00516 }
00517 //------------------------------------------------------------------------------
00518 void OpenGLContext::applyRenderStates( const RenderStateSet* new_rs, const Camera* camera) // mic fixme: this camera can also be taken away
00519 {
00520   VL_CHECK_OGL()
00521 
00522   mNewRenderStateSet->clear();
00523 
00524   if (new_rs)
00525   {
00526     for( size_t i=0; i<new_rs->renderStatesCount(); ++i )
00527     {
00528       const RenderStateSlot& rs = new_rs->renderStates()[i];
00529       mNewRenderStateSet->append(rs.type(), rs);
00530       if (!mCurrentRenderStateSet->hasKey(rs.type()) || rs.mRS.get() != mCurrentRenderStateSet->valueFromKey(rs.type()).mRS.get())
00531       {
00532         VL_CHECK(rs.mRS.get());
00533         rs.apply(camera, this); VL_CHECK_OGL()
00534       }
00535     }
00536   }
00537 
00538   for( RenderStateSlot* rs = mCurrentRenderStateSet->begin(); rs != mCurrentRenderStateSet->end(); ++rs)
00539   {
00540     if (!mNewRenderStateSet->hasKey(rs->type()))
00541     {
00542       mDefaultRenderStates[rs->type()].apply(NULL, this); VL_CHECK_OGL()
00543     }
00544   }
00545 
00546   std::swap(mNewRenderStateSet, mCurrentRenderStateSet);
00547 }
00548 //------------------------------------------------------------------------------
00549 void OpenGLContext::setupDefaultRenderStates()
00550 {
00551   if ( Has_Fixed_Function_Pipeline )
00552   {
00553     mDefaultRenderStates[RS_Color]  = RenderStateSlot(new Color, 0);
00554     mDefaultRenderStates[RS_SecondaryColor]  = RenderStateSlot(new SecondaryColor, 0);
00555     mDefaultRenderStates[RS_Normal]  = RenderStateSlot(new Normal, 0);
00556 
00557     mDefaultRenderStates[RS_AlphaFunc]  = RenderStateSlot(new AlphaFunc, 0);
00558     mDefaultRenderStates[RS_Fog]        = RenderStateSlot(new Fog, 0);
00559     mDefaultRenderStates[RS_ShadeModel] = RenderStateSlot(new ShadeModel, 0);
00560     mDefaultRenderStates[RS_LightModel] = RenderStateSlot(new LightModel, 0);
00561     mDefaultRenderStates[RS_Material]   = RenderStateSlot(new Material, 0);
00562     if(!Has_GLES_Version_1_1)
00563     {
00564       mDefaultRenderStates[RS_PixelTransfer]  = RenderStateSlot(new PixelTransfer, 0);
00565       mDefaultRenderStates[RS_LineStipple]    = RenderStateSlot(new LineStipple, 0);
00566       mDefaultRenderStates[RS_PolygonStipple] = RenderStateSlot(new PolygonStipple, 0);
00567     }
00568 
00569     mDefaultRenderStates[RS_Light0] = RenderStateSlot(new Light, 0); mDefaultRenderStates[RS_Light0].mRS->as<Light>()->setEnabled(false);
00570     mDefaultRenderStates[RS_Light1] = RenderStateSlot(new Light, 1); mDefaultRenderStates[RS_Light1].mRS->as<Light>()->setEnabled(false);
00571     mDefaultRenderStates[RS_Light2] = RenderStateSlot(new Light, 2); mDefaultRenderStates[RS_Light2].mRS->as<Light>()->setEnabled(false);
00572     mDefaultRenderStates[RS_Light3] = RenderStateSlot(new Light, 3); mDefaultRenderStates[RS_Light3].mRS->as<Light>()->setEnabled(false);
00573     mDefaultRenderStates[RS_Light4] = RenderStateSlot(new Light, 4); mDefaultRenderStates[RS_Light4].mRS->as<Light>()->setEnabled(false);
00574     mDefaultRenderStates[RS_Light5] = RenderStateSlot(new Light, 5); mDefaultRenderStates[RS_Light5].mRS->as<Light>()->setEnabled(false);
00575     mDefaultRenderStates[RS_Light6] = RenderStateSlot(new Light, 6); mDefaultRenderStates[RS_Light6].mRS->as<Light>()->setEnabled(false);
00576     mDefaultRenderStates[RS_Light7] = RenderStateSlot(new Light, 7); mDefaultRenderStates[RS_Light7].mRS->as<Light>()->setEnabled(false);
00577 
00578     mDefaultRenderStates[RS_ClipPlane0] = RenderStateSlot(new ClipPlane, 0); mDefaultRenderStates[RS_ClipPlane0].mRS->as<ClipPlane>()->setEnabled(false);
00579     mDefaultRenderStates[RS_ClipPlane1] = RenderStateSlot(new ClipPlane, 1); mDefaultRenderStates[RS_ClipPlane1].mRS->as<ClipPlane>()->setEnabled(false);
00580     mDefaultRenderStates[RS_ClipPlane2] = RenderStateSlot(new ClipPlane, 2); mDefaultRenderStates[RS_ClipPlane2].mRS->as<ClipPlane>()->setEnabled(false);
00581     mDefaultRenderStates[RS_ClipPlane3] = RenderStateSlot(new ClipPlane, 3); mDefaultRenderStates[RS_ClipPlane3].mRS->as<ClipPlane>()->setEnabled(false);
00582     mDefaultRenderStates[RS_ClipPlane4] = RenderStateSlot(new ClipPlane, 4); mDefaultRenderStates[RS_ClipPlane4].mRS->as<ClipPlane>()->setEnabled(false);
00583     mDefaultRenderStates[RS_ClipPlane5] = RenderStateSlot(new ClipPlane, 5); mDefaultRenderStates[RS_ClipPlane5].mRS->as<ClipPlane>()->setEnabled(false);
00584   }
00585 
00586   if (Has_GL_EXT_blend_color||Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0||Has_GLES_Version_2_0)
00587     mDefaultRenderStates[RS_BlendColor] = RenderStateSlot(new BlendColor, 0);
00588 
00589   if (Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0||Has_GL_OES_blend_subtract||Has_GLES_Version_2_0)
00590     mDefaultRenderStates[RS_BlendEquation] = RenderStateSlot(new BlendEquation, 0);
00591 
00592   if(!Has_GLES)
00593     mDefaultRenderStates[RS_PolygonMode] = RenderStateSlot(new PolygonMode, 0);
00594 
00595   if(!Has_GLES_Version_2_0)
00596   {
00597     mDefaultRenderStates[RS_LogicOp] = RenderStateSlot(new LogicOp, 0);
00598     mDefaultRenderStates[RS_PointSize] = RenderStateSlot(new PointSize, 0);
00599   }
00600 
00601   mDefaultRenderStates[RS_PolygonOffset] = RenderStateSlot(new PolygonOffset, 0);
00602   mDefaultRenderStates[RS_BlendFunc]  = RenderStateSlot(new BlendFunc, 0);
00603   mDefaultRenderStates[RS_ColorMask]  = RenderStateSlot(new ColorMask, 0);
00604   mDefaultRenderStates[RS_CullFace]   = RenderStateSlot(new CullFace, 0);
00605   mDefaultRenderStates[RS_DepthFunc]  = RenderStateSlot(new DepthFunc, 0);
00606   mDefaultRenderStates[RS_DepthMask]  = RenderStateSlot(new DepthMask, 0);
00607   mDefaultRenderStates[RS_DepthRange] = RenderStateSlot(new DepthRange, 0);
00608   mDefaultRenderStates[RS_FrontFace]  = RenderStateSlot(new FrontFace, 0);
00609   mDefaultRenderStates[RS_Hint]       = RenderStateSlot(new Hint, 0);
00610   mDefaultRenderStates[RS_LineWidth]  = RenderStateSlot(new LineWidth, 0);
00611   
00612   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
00613     mDefaultRenderStates[RS_PointParameter] = RenderStateSlot(new PointParameter, 0);
00614 
00615   if (Has_GL_ARB_multisample||Has_GL_Version_1_3||Has_GL_Version_3_0||Has_GL_Version_4_0||Has_GLES_Version_1_1||Has_GLES_Version_2_0)
00616     mDefaultRenderStates[RS_SampleCoverage] = RenderStateSlot(new SampleCoverage, 0);
00617   
00618   mDefaultRenderStates[RS_StencilFunc] = RenderStateSlot(new StencilFunc, 0);
00619   mDefaultRenderStates[RS_StencilMask] = RenderStateSlot(new StencilMask, 0);
00620   mDefaultRenderStates[RS_StencilOp]   = RenderStateSlot(new StencilOp, 0);
00621   mDefaultRenderStates[RS_GLSLProgram] = RenderStateSlot(new GLSLProgram, 0);
00622 
00623   for(int i=0; i<VL_MAX_TEXTURE_UNITS; ++i)
00624   {
00625     if (i < textureUnitCount())
00626     {
00627       mDefaultRenderStates[RS_TextureSampler + i] = RenderStateSlot(new TextureSampler, i);
00628       if( Has_Fixed_Function_Pipeline )
00629       {
00630         // TexGen under GLES is supported only if GL_OES_texture_cube_map is present
00631         if(!Has_GLES_Version_1_1 || Has_GL_OES_texture_cube_map)
00632           mDefaultRenderStates[RS_TexGen + i] = RenderStateSlot(new TexGen, i);
00633         mDefaultRenderStates[RS_TexEnv + i] = RenderStateSlot(new TexEnv, i);
00634         mDefaultRenderStates[RS_TextureMatrix + i] = RenderStateSlot(new TextureMatrix, i);
00635       }
00636     }
00637   }
00638 
00639   VL_CHECK_OGL();
00640 
00641   // applies default render states backwards so we don't need to call VL_glActiveTexture(GL_TEXTURE0) at the end.
00642   for( int i=RS_RenderStateCount; i--; )
00643   {
00644     // the empty ones are the ones that are not supported by the current OpenGL implementation (too old or Core profile)
00645     if (mDefaultRenderStates[i].mRS)
00646     {
00647       mDefaultRenderStates[i].apply(NULL, this); VL_CHECK_OGL();
00648     }
00649   }
00650 }
00651 //-----------------------------------------------------------------------------
00652 void OpenGLContext::resetRenderStates()
00653 {
00654   mCurrentRenderStateSet->clear();
00655   memset( mTexUnitBinding, 0, sizeof( mTexUnitBinding ) ); // set to unknown texture target
00656 }
00657 //-----------------------------------------------------------------------------
00658 void OpenGLContext::resetEnables()
00659 {
00660   mCurrentEnableSet->clear();
00661 }
00662 //------------------------------------------------------------------------------
00663 bool OpenGLContext::isCleanState(bool verbose)
00664 {
00665   VL_CHECK_OGL();
00666   String error_msg;
00667 
00668   // everything must be disabled except GL_DITHER and GL_MULTISAMPLE
00669   for( unsigned i=0; i<EN_EnableCount; ++i )
00670   {
00671     if (!Is_Enable_Supported[i])
00672       continue;
00673 
00674     if (i == EN_DITHER || i == EN_MULTISAMPLE)
00675       continue;
00676 
00677     GLboolean enabled = glIsEnabled( Translate_Enable[i] ); VL_CHECK_OGL();
00678 
00679     if (enabled)
00680     {
00681       error_msg += Say(" - Capability %s was enabled!\n") << Translate_Enable_String[i];
00682       glDisable(Translate_Enable[i]);
00683     }
00684   }
00685 
00686   if (Has_Fixed_Function_Pipeline)
00687   {
00688     int max_lights = 0;
00689     glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
00690 
00691     for( int i=0; i<max_lights; ++i)
00692     {
00693       if (glIsEnabled(GL_LIGHT0+i))
00694       {
00695         error_msg += Say(" - GL_LIGHT%n was enabled!\n") << i;
00696         glDisable(GL_LIGHT0+i);
00697       }
00698     }
00699 
00700     // OpenGL requires 6 planes but GLES 1.x requires only 1.
00701     int max_planes = 0;
00702     glGetIntegerv(GL_MAX_CLIP_PLANES, &max_planes);
00703 
00704     for( int i=0; i<max_planes; ++i)
00705     {
00706       if (glIsEnabled(GL_CLIP_PLANE0+i))
00707       {
00708         error_msg += Say(" - GL_CLIP_PLANE%n was enabled!\n") << i;
00709         glDisable(GL_CLIP_PLANE0+i);
00710       }
00711     }
00712   }
00713 
00714   if (Has_Primitive_Restart && glIsEnabled(GL_PRIMITIVE_RESTART))
00715   {
00716     error_msg += " - GL_PRIMITIVE_RESTART was enabled!\n";
00717     glDisable(GL_PRIMITIVE_RESTART);
00718   }
00719 
00720   if(Has_Multitexture)
00721   {
00722     int active_tex = -1;
00723     // mic fixme: PVR emulator bug? returns always 1.
00724 #if !defined(VL_OPENGL_ES2)
00725     glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex); VL_CHECK_OGL();
00726     active_tex -= GL_TEXTURE0;
00727     if (active_tex != 0)
00728     {
00729         error_msg += Say(" - Active texture unit is GL_TEXTURE%n instead of GL_TEXTURE0!\n") << active_tex;
00730         glActiveTexture(GL_TEXTURE0);
00731     }
00732 #endif
00733 
00734     if (Has_Fixed_Function_Pipeline)
00735     {
00736       active_tex = -1;
00737       glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &active_tex); VL_CHECK_OGL();
00738       active_tex -= GL_TEXTURE0;
00739       if (active_tex != 0)
00740       {
00741         error_msg += Say(" - Active client texture unit is GL_TEXTURE%n instead of GL_TEXTURE0!\n") << active_tex;
00742         glClientActiveTexture(GL_TEXTURE0);
00743       }
00744     }
00745   }
00746 
00747   VL_CHECK_OGL()
00748 
00749   /* We only check the subset of tex-units supported also by glClientActiveTexture() */
00750   // Find the minimum of the max texture units supported, starting at 16
00751   int coord_count = 16;
00752   if (Has_GL_ARB_multitexture||Has_GL_Version_1_3||Has_GLES_Version_1_1)
00753   {
00754     int max_tmp = 0;
00755     glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
00756     coord_count = max_tmp < coord_count ? max_tmp : coord_count;
00757   }
00758 
00759   VL_CHECK_OGL()
00760 
00761   if (Has_GLSL) // for GL >= 2.0
00762   {
00763     int max_tmp = 0;
00764     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_tmp); VL_CHECK_OGL();
00765     coord_count = max_tmp < coord_count ? max_tmp : coord_count;
00766   }
00767 
00768   if (Has_GL_Version_2_0) // for GL == 2.x && compatible higher
00769   {
00770     int max_tmp = 0;
00771     glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_tmp); VL_CHECK_OGL(); // deprecated enum
00772     coord_count = max_tmp < coord_count ? max_tmp : coord_count;
00773   }
00774 
00775   VL_CHECK_OGL()
00776 
00777   while(coord_count--)
00778   {
00779     VL_CHECK_OGL()
00780     VL_glActiveTexture(GL_TEXTURE0+coord_count); VL_CHECK_OGL()
00781 
00782     if (Has_Fixed_Function_Pipeline)
00783     {
00784         VL_glClientActiveTexture(GL_TEXTURE0+coord_count); VL_CHECK_OGL()
00785 
00786         float matrix[16];
00787         float imatrix[16];
00788         glGetFloatv(GL_TEXTURE_MATRIX, matrix); VL_CHECK_OGL()
00789         glMatrixMode(GL_TEXTURE); VL_CHECK_OGL()
00790         glLoadIdentity(); VL_CHECK_OGL()
00791         glGetFloatv(GL_TEXTURE_MATRIX, imatrix); VL_CHECK_OGL()
00792         // glLoadMatrixf(matrix); VL_CHECK_OGL() // we keep the identity
00793         if (memcmp(matrix,imatrix,sizeof(matrix)) != 0)
00794         {
00795           error_msg += Say(" - Texture matrix was not set to identity on texture unit %n!\n") << coord_count;
00796         }
00797     
00798         if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
00799         {
00800           error_msg += Say(" - GL_TEXTURE_COORD_ARRAY was enabled on texture unit %n!\n") << coord_count;
00801           glDisable(GL_TEXTURE_COORD_ARRAY);
00802         }
00803     
00804         // check that all texture targets are disabled and bound to texture #0
00805     
00806       if (!Has_GLES)
00807       {
00808           if (glIsEnabled(GL_TEXTURE_1D))
00809           {
00810             error_msg += Say(" - GL_TEXTURE_1D was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00811           glDisable(GL_TEXTURE_1D);
00812           }
00813     
00814         GLint bound_tex = 0;
00815           glGetIntegerv(GL_TEXTURE_BINDING_1D, &bound_tex); VL_CHECK_OGL()
00816           if (bound_tex != 0)
00817           {
00818             error_msg += Say(" - GL_TEXTURE_BINDING_1D != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00819           }
00820       }
00821     
00822         if (glIsEnabled(GL_TEXTURE_2D))
00823         {
00824           error_msg += Say(" - GL_TEXTURE_2D was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00825         glDisable(GL_TEXTURE_2D);
00826         }
00827     }
00828 
00829     GLint bound_tex = 0;
00830     glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_tex); VL_CHECK_OGL()
00831     if (bound_tex != 0)
00832     {
00833       error_msg += Say(" - GL_TEXTURE_BINDING_2D != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00834     }
00835 
00836     if (Has_Texture_Rectangle)
00837     {
00838       if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_TEXTURE_RECTANGLE))
00839       {
00840         error_msg += Say(" - GL_TEXTURE_RECTANGLE was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00841         glDisable(GL_TEXTURE_RECTANGLE);
00842       }
00843 
00844       bound_tex = 0;
00845       glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE, &bound_tex); VL_CHECK_OGL()
00846       if (bound_tex != 0)
00847       {
00848         error_msg += Say(" - GL_TEXTURE_BINDING_RECTANGLE != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00849       }
00850     }
00851 
00852     if (Has_Texture_3D)
00853     {
00854       if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_TEXTURE_3D))
00855       {
00856         error_msg += Say(" - GL_TEXTURE_3D was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00857         glDisable(GL_TEXTURE_3D);
00858       }
00859 
00860       bound_tex = 0;
00861       glGetIntegerv(GL_TEXTURE_BINDING_3D, &bound_tex); VL_CHECK_OGL()
00862       if (bound_tex != 0)
00863       {
00864         error_msg += Say(" - GL_TEXTURE_BINDING_3D != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00865       }
00866     }
00867 
00868     if (Has_Cubemap_Textures)
00869     {
00870       if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_TEXTURE_CUBE_MAP))
00871       {
00872         error_msg += Say(" - GL_TEXTURE_CUBE_MAP was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00873         glDisable(GL_TEXTURE_CUBE_MAP);
00874       }
00875 
00876       bound_tex = 0;
00877       glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &bound_tex); VL_CHECK_OGL()
00878       if (bound_tex != 0)
00879       {
00880         error_msg += Say(" - GL_TEXTURE_BINDING_CUBE_MAP != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00881       }
00882     }
00883 
00884     if (Has_Texture_Array)
00885     {
00886       bound_tex = 0;
00887       glGetIntegerv(GL_TEXTURE_BINDING_1D_ARRAY, &bound_tex);
00888       if (bound_tex != 0)
00889       {
00890         error_msg += Say(" - GL_TEXTURE_BINDING_1D_ARRAY != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00891       }
00892 
00893       bound_tex = 0;
00894       glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, &bound_tex);
00895       if (bound_tex != 0)
00896       {
00897         error_msg += Say(" - GL_TEXTURE_BINDING_2D_ARRAY != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00898       }
00899     }
00900 
00901     if (Has_Texture_Multisample)
00902     {
00903       bound_tex = 0;
00904       glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &bound_tex);
00905       if (bound_tex != 0)
00906       {
00907         error_msg += Say(" - GL_TEXTURE_BINDING_2D_MULTISAMPLE != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00908       }
00909 
00910       bound_tex = 0;
00911       glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, &bound_tex);
00912       if (bound_tex != 0)
00913       {
00914         error_msg += Say(" - GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00915       }
00916     }
00917 
00918     if (Has_Texture_Buffer)
00919     {
00920       bound_tex = 0;
00921       glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &bound_tex);
00922       if (bound_tex != 0)
00923       {
00924         error_msg += Say(" - GL_TEXTURE_BINDING_BUFFER != 0 on texture unit GL_TEXTURE%n.\n") << coord_count;
00925       }
00926     }
00927 
00928     if (Has_Fixed_Function_Pipeline)
00929     {
00930 #if defined(VL_OPENGL)
00931         if (glIsEnabled(GL_TEXTURE_GEN_S))
00932         {
00933           error_msg += Say(" - GL_TEXTURE_GEN_S was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00934         glDisable(GL_TEXTURE_GEN_S);
00935         }
00936     
00937         if (glIsEnabled(GL_TEXTURE_GEN_T))
00938         {
00939           error_msg += Say(" - GL_TEXTURE_GEN_T was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00940         glDisable(GL_TEXTURE_GEN_T);
00941         }
00942     
00943         if (glIsEnabled(GL_TEXTURE_GEN_R))
00944         {
00945           error_msg += Say(" - GL_TEXTURE_GEN_R was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00946         glDisable(GL_TEXTURE_GEN_R);
00947         }
00948     
00949         if (glIsEnabled(GL_TEXTURE_GEN_Q))
00950         {
00951           error_msg += Say(" - GL_TEXTURE_GEN_Q was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00952         glDisable(GL_TEXTURE_GEN_Q);
00953         }
00954 #elif defined(VL_OPENGL_ES1)
00955         if (Has_GL_OES_texture_cube_map && glIsEnabled(GL_TEXTURE_GEN_STR_OES))
00956         {
00957           error_msg += Say(" - GL_TEXTURE_GEN_STR_OES was enabled on texture unit GL_TEXTURE%n.\n") << coord_count;
00958         glDisable(GL_TEXTURE_GEN_STR_OES);
00959         }
00960 #endif
00961     }
00962   }
00963 
00964   if (Has_GL_Version_1_1 && glIsEnabled(GL_COLOR_MATERIAL)) // excludes also GLES
00965   {
00966     error_msg += " - GL_COLOR_MATERIAL was enabled!\n";
00967     glDisable(GL_COLOR_MATERIAL);
00968   }
00969 
00970   if (Has_GL_Version_1_4 || Has_GL_EXT_fog_coord) // excludes also GLES 1.x
00971   {
00972     if (glIsEnabled(GL_FOG_COORD_ARRAY))
00973     {
00974       error_msg += " - GL_FOG_COORD_ARRAY was enabled!\n";
00975       glDisable(GL_FOG_COORD_ARRAY);
00976     }
00977   }
00978 
00979   if (Has_GL_Version_1_4 || Has_GL_EXT_secondary_color) // excludes also GLES 1.x
00980   {
00981     if (glIsEnabled(GL_SECONDARY_COLOR_ARRAY))
00982     {
00983       error_msg += " - GL_SECONDARY_COLOR_ARRAY was enabled!\n";
00984       glDisable(GL_SECONDARY_COLOR_ARRAY);
00985     }
00986   }
00987 
00988   if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_COLOR_ARRAY)) // includes GLES 1.x
00989   {
00990     error_msg += " - GL_COLOR_ARRAY was enabled!\n";
00991     glDisable(GL_COLOR_ARRAY);
00992   }
00993 
00994   if (Has_GL_Version_1_1 && glIsEnabled(GL_EDGE_FLAG_ARRAY)) // excludes GLES 
00995   {
00996     error_msg += " - GL_EDGE_FLAG_ARRAY was enabled!\n";
00997     glDisable(GL_EDGE_FLAG_ARRAY);
00998   }
00999 
01000   if (Has_GL_Version_1_1 && glIsEnabled(GL_INDEX_ARRAY)) // excludes GLES
01001   {
01002     error_msg += " - GL_INDEX_ARRAY was enabled!\n";
01003     glDisable(GL_INDEX_ARRAY);
01004   }
01005 
01006   if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_NORMAL_ARRAY)) // includes GLES 1.x
01007   {
01008     error_msg += " - GL_NORMAL_ARRAY was enabled!\n";
01009     glDisable(GL_NORMAL_ARRAY);
01010   }
01011 
01012   if (Has_Fixed_Function_Pipeline && glIsEnabled(GL_VERTEX_ARRAY)) // includes GLES 1.x
01013   {
01014     error_msg += " - GL_VERTEX_ARRAY was enabled!\n";
01015     glDisable(GL_VERTEX_ARRAY);
01016   }
01017 
01018   if (glIsEnabled(GL_SCISSOR_TEST))
01019   {
01020     error_msg += " - GL_SCISSOR_TEST was enabled!\n";
01021     glDisable(GL_SCISSOR_TEST);
01022   }
01023 
01024   GLint max_vert_attribs = 0;
01025   if (Has_GLSL)
01026     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vert_attribs);
01027   for(int i=0; i<max_vert_attribs; ++i)
01028   {
01029     GLint is_enabled = 0;
01030     glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &is_enabled);
01031     if (is_enabled)
01032     {
01033       error_msg += Say(" - GL_VERTEX_ATTRIB_ARRAY #%n is enabled!\n") << i;
01034     }
01035   }
01036 
01037   if (Has_GL_ARB_imaging)
01038   {
01039     if (glIsEnabled(GL_HISTOGRAM))
01040     {
01041       error_msg += " - GL_HISTOGRAM was enabled!\n";
01042       glDisable(GL_HISTOGRAM);
01043     }
01044 
01045     if (glIsEnabled(GL_MINMAX))
01046     {
01047       error_msg += " - GL_MINMAX was enabled!\n";
01048       glDisable(GL_MINMAX);
01049     }
01050   }
01051 
01052   // we expect these settings for the default blending equation
01053 #if defined(VL_OPENGL_ES2)
01054   GLint blend_src = 0;
01055   GLint blend_dst = 0;
01056   glGetIntegerv( GL_BLEND_SRC_RGB, &blend_src ); VL_CHECK_OGL();
01057   glGetIntegerv( GL_BLEND_DST_RGB, &blend_dst ); VL_CHECK_OGL();
01058   if (blend_src != GL_SRC_ALPHA)
01059   {
01060     error_msg += " - GL_BLEND_SRC is not GL_SRC_ALPHA!\n";
01061     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01062   }
01063   if (blend_dst != GL_ONE_MINUS_SRC_ALPHA)
01064   {
01065     error_msg += " - GL_BLEND_DST is not GL_ONE_MINUS_SRC_ALPHA!\n";
01066     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01067   }
01068 #else
01069   GLint blend_src = 0;
01070   GLint blend_dst = 0;
01071   glGetIntegerv( GL_BLEND_SRC, &blend_src ); VL_CHECK_OGL();
01072   glGetIntegerv( GL_BLEND_DST, &blend_dst ); VL_CHECK_OGL();
01073   if (blend_src != GL_SRC_ALPHA)
01074   {
01075     error_msg += " - GL_BLEND_SRC is not GL_SRC_ALPHA!\n";
01076     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01077   }
01078   if (blend_dst != GL_ONE_MINUS_SRC_ALPHA)
01079   {
01080     error_msg += " - GL_BLEND_DST is not GL_ONE_MINUS_SRC_ALPHA!\n";
01081     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01082   }
01083 #endif
01084 
01085   // buffer object bindings
01086 
01087   GLint buf_bind = 0;
01088   if (Has_BufferObject)
01089   {
01090     glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
01091     if (buf_bind != 0)
01092     {
01093       error_msg += " - GL_ARRAY_BUFFER_BINDING should be 0!\n";
01094     }
01095     buf_bind = 0;
01096     glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
01097     if (buf_bind != 0)
01098     {
01099       error_msg += " - GL_ELEMENT_ARRAY_BUFFER_BINDING should be 0!\n";
01100     }
01101   }
01102   if (Has_GL_Version_2_1)
01103   {
01104     buf_bind = 0;
01105     glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
01106     if (buf_bind != 0)
01107     {
01108       error_msg += " - GL_PIXEL_PACK_BUFFER_BINDING should be 0!\n";
01109     }
01110     buf_bind = 0;
01111     glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
01112     if (buf_bind != 0)
01113     {
01114       error_msg += " - GL_PIXEL_UNPACK_BUFFER_BINDING should be 0!\n";
01115     }
01116   }
01117   if (Has_GL_ARB_uniform_buffer_object)
01118   {
01119     buf_bind = 0;
01120     glGetIntegerv(GL_UNIFORM_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
01121     if (buf_bind != 0)
01122     {
01123       error_msg += " - GL_UNIFORM_BUFFER_BINDING should be 0!\n";
01124     }
01125   }
01126   if(Has_Transform_Feedback)
01127   {
01128     buf_bind = 0;
01129     glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &buf_bind); VL_CHECK_OGL();
01130     if (buf_bind != 0)
01131     {
01132       error_msg += " - GL_TRANSFORM_FEEDBACK_BUFFER_BINDING should be 0!\n";
01133     }
01134   }
01135 
01136   #if 0
01137   // check viewport
01138   GLint viewport[4] = {0,0,0,0};
01139   glGetIntegerv(GL_VIEWPORT, viewport);
01140   if (viewport[2] * viewport[3] == 1)
01141   {
01142     error_msg += " - Viewport dimension is 1 pixel!\n"
01143     "Did you forget to call camera()->viewport()->setWidth()/setHeight() upon window resize event?\n";
01144   }
01145   #endif
01146 
01147   GLboolean write_mask[4];
01148   glGetBooleanv(GL_COLOR_WRITEMASK, write_mask); VL_CHECK_OGL();
01149   if( !write_mask[0] || !write_mask[1] || !write_mask[2] || !write_mask[3] )
01150   {
01151     error_msg += " - Color write-mask should be glColorMask(GL_TRUE ,GL_TRUE, GL_TRUE, GL_TRUE)!\n";
01152     glColorMask(GL_TRUE ,GL_TRUE, GL_TRUE, GL_TRUE);
01153   }
01154 
01155   glGetBooleanv(GL_DEPTH_WRITEMASK, write_mask); VL_CHECK_OGL();
01156   if ( !write_mask[0] )
01157   {
01158     error_msg += " - Depth write-mask should be glDepthMask(GL_TRUE)!\n";
01159     glDepthMask(GL_TRUE);
01160   }
01161 
01162 #if defined(VL_OPENGL)
01163   GLint poly_mode[2];
01164   glGetIntegerv(GL_POLYGON_MODE, poly_mode); VL_CHECK_OGL();
01165   if ( poly_mode[0] != GL_FILL || poly_mode[1] != GL_FILL )
01166   {
01167     error_msg += " - Polygon mode should be glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)!\n";
01168     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01169   }
01170 #endif
01171 
01172   if (!error_msg.empty() && verbose)
01173   {
01174     Log::error("Dirty OpenGL context state:\n");
01175     Log::error(error_msg);
01176     Log::error("To disable this check use globalSettings()->setCheckOpenGLStates(false);\n");
01177     Log::error( Say("Driver info: %s, %s, OpenGL %s\n") 
01178                 << glGetString(GL_VENDOR) << glGetString(GL_RENDERER) << glGetString(GL_VERSION) );
01179   }
01180 
01181   VL_CHECK_OGL(); 
01182 
01183   return error_msg.empty();
01184 }
01185 //-----------------------------------------------------------------------------
01186 bool OpenGLContext::areUniformsColliding(const UniformSet* u1, const UniformSet* u2)
01187 {
01188   if (!u1 || !u2)
01189     return false;
01190 
01191   // compile the map
01192   std::set<std::string> name_set;
01193   for( size_t i=0; i<u1->uniforms().size(); ++i )
01194     name_set.insert( u1->uniforms()[i]->name() );
01195 
01196   bool ok = false;
01197   // check the map
01198   for( size_t j=0; j<u2->uniforms().size(); ++j )
01199     if ( name_set.find( u2->uniforms()[j]->name() ) != name_set.end() )
01200     {
01201       vl::Log::error( Say("Uniform name collision detected: %s\n") << u2->uniforms()[j]->name() );
01202       ok = true;
01203     }
01204 
01205   return ok;
01206 }
01207 //-----------------------------------------------------------------------------
01208 void OpenGLContext::resetContextStates(EResetContextStates start_or_finish)
01209 {
01210   // Check that the OpenGL state is clear.
01211   // If this fails use VL_CHECK_OGL to make sure your application does not generate OpenGL errors.
01212   // See also glGetError() -> http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml
01213   VL_CHECK_OGL();
01214 
01215   // perform extra OpenGL environment sanity check
01216   if (globalSettings()->checkOpenGLStates())
01217     isCleanState(true);
01218 
01219   VL_glBindFramebuffer(GL_FRAMEBUFFER, 0); VL_CHECK_OGL();
01220 
01221   // not existing under OpenGL ES 1 and 2
01222 #if defined(VL_OPENGL)
01223   if ( hasDoubleBuffer() )
01224   {
01225     glDrawBuffer(GL_BACK); VL_CHECK_OGL();
01226     glReadBuffer(GL_BACK); VL_CHECK_OGL();
01227   }
01228   else
01229   {
01230     glDrawBuffer(GL_FRONT); VL_CHECK_OGL();
01231     glReadBuffer(GL_FRONT); VL_CHECK_OGL();
01232   }
01233 #endif
01234 
01235   // these need to be cleaned up only when rendering starts
01236 
01237   if (start_or_finish == RCS_RenderingStarted)
01238   {
01239     // reset internal VL enables & render states tables
01240     resetEnables();
01241     resetRenderStates();
01242 
01243     // reset Vertex Attrib Set tables and also calls "glBindBuffer(GL_ARRAY_BUFFER, 0)"
01244     bindVAS(NULL, false, true); VL_CHECK_OGL();
01245   }
01246 }
01247 //-----------------------------------------------------------------------------
01248 void OpenGLContext::bindVAS(const IVertexAttribSet* vas, bool use_bo, bool force)
01249 {
01250   VL_CHECK_OGL();
01251 
01252   // bring opengl to a known state
01253 
01254   if (vas != mCurVAS || force)
01255   {
01256 
01257     if (!vas || force)
01258     {
01259       mCurVAS = NULL;
01260 
01261       // reset all internal states
01262 
01263       for(int i=0; i<VL_MAX_GENERIC_VERTEX_ATTRIB; ++i)
01264       {
01265         mVertexAttrib[i].mEnabled = false; // not used
01266         mVertexAttrib[i].mPtr = 0;
01267         mVertexAttrib[i].mBufferObject = 0;
01268         mVertexAttrib[i].mState = 0;
01269       }
01270 
01271       for(int i=0; i<VL_MAX_TEXTURE_UNITS; ++i)
01272       {
01273         mTexCoordArray[i].mEnabled = false; // not used
01274         mTexCoordArray[i].mPtr = 0;
01275         mTexCoordArray[i].mBufferObject = 0;
01276         mTexCoordArray[i].mState = 0;
01277       }
01278 
01279       mVertexArray.mEnabled = false;
01280       mVertexArray.mPtr = 0;
01281       mVertexArray.mBufferObject = 0;
01282       mVertexArray.mState = 0; // not used
01283 
01284       mNormalArray.mEnabled = false;
01285       mNormalArray.mPtr = 0;
01286       mNormalArray.mBufferObject = 0;
01287       mNormalArray.mState = 0; // not used
01288 
01289       mColorArray.mEnabled = false;
01290       mColorArray.mPtr = 0;
01291       mColorArray.mBufferObject = 0;
01292       mColorArray.mState = 0; // not used
01293 
01294       mSecondaryColorArray.mEnabled = false;
01295       mSecondaryColorArray.mPtr = 0;
01296       mSecondaryColorArray.mBufferObject = 0;
01297       mSecondaryColorArray.mState = 0; // not used
01298 
01299       mFogArray.mEnabled = false;
01300       mFogArray.mPtr = 0;
01301       mFogArray.mBufferObject = 0;
01302       mFogArray.mState = 0; // not used
01303 
01304       // reset all gl states
01305 
01306       for(int i=0; i<mMaxVertexAttrib; ++i)
01307         VL_glDisableVertexAttribArray(i); VL_CHECK_OGL();
01308 
01309       // note this one
01310       VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); VL_CHECK_OGL();
01311 
01312       VL_glBindBuffer(GL_ARRAY_BUFFER, 0); VL_CHECK_OGL();
01313 
01314       if(Has_Fixed_Function_Pipeline)
01315       {
01316         // iterate backwards so the last active is #0
01317         for ( int i=mTextureSamplerCount; i--; )
01318         {
01319           VL_glClientActiveTexture(GL_TEXTURE0 + i); VL_CHECK_OGL();
01320           glDisableClientState(GL_TEXTURE_COORD_ARRAY); VL_CHECK_OGL();
01321         }
01322 
01323         glDisableClientState(GL_VERTEX_ARRAY); VL_CHECK_OGL();
01324         glDisableClientState(GL_NORMAL_ARRAY); VL_CHECK_OGL();
01325         glDisableClientState(GL_COLOR_ARRAY); VL_CHECK_OGL();
01326 
01327         // not supported under GLES
01328 #if defined(VL_OPENGL)
01329         glDisableClientState(GL_SECONDARY_COLOR_ARRAY); VL_CHECK_OGL();
01330         glDisableClientState(GL_FOG_COORD_ARRAY); VL_CHECK_OGL();
01331 #endif
01332       }
01333     }
01334 
01335     if (vas)
01336     {
01337       int buf_obj = 0;
01338       const unsigned char* ptr = 0;
01339       bool enabled = false;
01340 
01341       if(Has_Fixed_Function_Pipeline)
01342       {
01343 
01344         // ----- vertex array -----
01345 
01346         enabled = vas->vertexArray() != NULL;
01347         if ( mVertexArray.mEnabled || enabled )
01348         {
01349           if (enabled)
01350           {
01351             if ( use_bo && vas->vertexArray()->bufferObject()->handle() )
01352             {
01353               buf_obj = vas->vertexArray()->bufferObject()->handle();
01354               ptr = 0;
01355             }
01356             else
01357             {
01358               buf_obj = 0;
01359               ptr = vas->vertexArray()->bufferObject()->ptr();
01360             }
01361             if ( mVertexArray.mPtr != ptr || mVertexArray.mBufferObject != buf_obj )
01362             {
01363               if (!mVertexArray.mEnabled)
01364               {
01365                 glEnableClientState(GL_VERTEX_ARRAY); VL_CHECK_OGL();
01366               }
01367               // mic fixme:
01368               // Note: for the moment we threat glBindBuffer and glVertexPointer as an atomic operation.
01369               // In the future we'll want to eliminate all direct calls to glBindBuffer and similar an
01370               // go through the OpenGLContext that will lazily do everything.
01371               VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
01372               glVertexPointer((int)vas->vertexArray()->glSize(), vas->vertexArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
01373               mVertexArray.mPtr = ptr;
01374               mVertexArray.mBufferObject = buf_obj;
01375             }
01376           }
01377           else
01378           {
01379             glDisableClientState(GL_VERTEX_ARRAY); VL_CHECK_OGL();
01380             mVertexArray.mPtr = 0;
01381             mVertexArray.mBufferObject = 0;
01382           }
01383           mVertexArray.mEnabled = enabled;
01384         }
01385 
01386         // ----- normal array -----
01387 
01388         enabled = vas->normalArray() != NULL;
01389         if ( mNormalArray.mEnabled || enabled )
01390         {
01391           if (enabled)
01392           {
01393             if ( use_bo && vas->normalArray()->bufferObject()->handle() )
01394             {
01395               buf_obj = vas->normalArray()->bufferObject()->handle();
01396               ptr = 0;
01397             }
01398             else
01399             {
01400               buf_obj = 0;
01401               ptr = vas->normalArray()->bufferObject()->ptr();
01402             }
01403             if ( mNormalArray.mPtr != ptr || mNormalArray.mBufferObject != buf_obj )
01404             {
01405               if (!mNormalArray.mEnabled)
01406               {
01407                 glEnableClientState(GL_NORMAL_ARRAY); VL_CHECK_OGL();
01408               }
01409               VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL(); 
01410               glNormalPointer(vas->normalArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
01411               mNormalArray.mPtr = ptr;
01412               mNormalArray.mBufferObject = buf_obj;
01413             }
01414           }
01415           else
01416           {
01417             glDisableClientState(GL_NORMAL_ARRAY); VL_CHECK_OGL();
01418 
01419             // restore constant normal
01420             glNormal3f( mNormal.x(), mNormal.y(), mNormal.z() );
01421 
01422             mNormalArray.mPtr = 0;
01423             mNormalArray.mBufferObject = 0;
01424           }
01425           mNormalArray.mEnabled = enabled;
01426         }
01427 
01428         // ----- color array -----
01429 
01430         enabled = vas->colorArray() != NULL;
01431         if ( mColorArray.mEnabled || enabled )
01432         {
01433           if (enabled)
01434           {
01435             if ( use_bo && vas->colorArray()->bufferObject()->handle() )
01436             {
01437               buf_obj = vas->colorArray()->bufferObject()->handle();
01438               ptr = 0;
01439             }
01440             else
01441             {
01442               buf_obj = 0;
01443               ptr = vas->colorArray()->bufferObject()->ptr();
01444             }
01445             if ( mColorArray.mPtr != ptr || mColorArray.mBufferObject != buf_obj )
01446             {
01447               if (!mColorArray.mEnabled)
01448               {
01449                 glEnableClientState(GL_COLOR_ARRAY); VL_CHECK_OGL();
01450               }
01451               VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
01452               glColorPointer((int)vas->colorArray()->glSize(), vas->colorArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
01453               mColorArray.mPtr = ptr;
01454               mColorArray.mBufferObject = buf_obj;
01455             }
01456           }
01457           else
01458           {
01459             glDisableClientState(GL_COLOR_ARRAY); VL_CHECK_OGL();
01460 
01461             // restore constant color
01462             glColor4f( mColor.r(), mColor.g(), mColor.b(), mColor.a() );
01463 
01464             mColorArray.mPtr = 0;
01465             mColorArray.mBufferObject = 0;
01466           }
01467           mColorArray.mEnabled = enabled;
01468         }
01469 
01470         // ----- secondary color array -----
01471 
01472         enabled = vas->secondaryColorArray() != NULL;
01473         if ( mSecondaryColorArray.mEnabled || enabled )
01474         {
01475           if (enabled)
01476           {
01477             if ( use_bo && vas->secondaryColorArray()->bufferObject()->handle() )
01478             {
01479               buf_obj = vas->secondaryColorArray()->bufferObject()->handle();
01480               ptr = 0;
01481             }
01482             else
01483             {
01484               buf_obj = 0;
01485               ptr = vas->secondaryColorArray()->bufferObject()->ptr();
01486             }
01487             if ( mSecondaryColorArray.mPtr != ptr || mSecondaryColorArray.mBufferObject != buf_obj )
01488             {
01489               if (!mSecondaryColorArray.mEnabled)
01490               {
01491                 glEnableClientState(GL_SECONDARY_COLOR_ARRAY); VL_CHECK_OGL();
01492               }
01493               VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
01494               glSecondaryColorPointer((int)vas->secondaryColorArray()->glSize(), vas->secondaryColorArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
01495               mSecondaryColorArray.mPtr = ptr;
01496               mSecondaryColorArray.mBufferObject = buf_obj;
01497             }
01498           }
01499           else
01500           {
01501             glDisableClientState(GL_SECONDARY_COLOR_ARRAY); VL_CHECK_OGL();
01502 
01503             // restore constant secondary color
01504             VL_glSecondaryColor3f( mSecondaryColor.r(), mSecondaryColor.g(), mSecondaryColor.b() );
01505 
01506             mSecondaryColorArray.mPtr = 0;
01507             mSecondaryColorArray.mBufferObject = 0;
01508           }
01509           mSecondaryColorArray.mEnabled = enabled;
01510         }
01511 
01512         // ----- fog array -----
01513 
01514         enabled = vas->fogCoordArray() != NULL;
01515         if ( mFogArray.mEnabled || enabled )
01516         {
01517           if (enabled)
01518           {
01519             if ( use_bo && vas->fogCoordArray()->bufferObject()->handle() )
01520             {
01521               buf_obj = vas->fogCoordArray()->bufferObject()->handle();
01522               ptr = 0;
01523             }
01524             else
01525             {
01526               buf_obj = 0;
01527               ptr = vas->fogCoordArray()->bufferObject()->ptr();
01528             }
01529             if ( mFogArray.mPtr != ptr || mFogArray.mBufferObject != buf_obj )
01530             {
01531               if (!mFogArray.mEnabled)
01532               {
01533                 glEnableClientState(GL_FOG_COORD_ARRAY); VL_CHECK_OGL();
01534               }
01535               VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
01536               glFogCoordPointer(vas->fogCoordArray()->glType(), /*stride*/0, ptr); VL_CHECK_OGL();
01537               mFogArray.mPtr = ptr;
01538               mFogArray.mBufferObject = buf_obj;
01539             }
01540           }
01541           else
01542           {
01543             glDisableClientState(GL_FOG_COORD_ARRAY); VL_CHECK_OGL();
01544             mFogArray.mPtr = 0;
01545             mFogArray.mBufferObject = 0;
01546           }
01547           mFogArray.mEnabled = enabled;
01548         }
01549 
01550         // ----- texture coords -----
01551 
01552         // (1) enable pass
01553         for(int i=0; i<vas->texCoordArrayCount(); ++i)
01554         {
01555           // texture array info
01556           const ArrayAbstract* texarr = NULL;
01557           int tex_unit = 0;
01558           vas->getTexCoordArrayAt(i, tex_unit, texarr);
01559           VL_CHECK(tex_unit<VL_MAX_TEXTURE_UNITS);
01560 
01561           mTexCoordArray[tex_unit].mState += 1; // 0 -> 1; 1 -> 2;
01562           VL_CHECK( mTexCoordArray[tex_unit].mState == 1 || mTexCoordArray[tex_unit].mState == 2 );
01563 
01564           if ( use_bo && texarr->bufferObject()->handle() )
01565           {
01566             buf_obj = texarr->bufferObject()->handle();
01567             ptr = 0;
01568           }
01569           else
01570           {
01571             buf_obj = 0;
01572             ptr = texarr->bufferObject()->ptr();
01573           }
01574           if ( mTexCoordArray[tex_unit].mPtr != ptr || mTexCoordArray[tex_unit].mBufferObject != buf_obj )
01575           {
01576             mTexCoordArray[tex_unit].mPtr = ptr;
01577             mTexCoordArray[tex_unit].mBufferObject = buf_obj;
01578 
01579             VL_glClientActiveTexture(GL_TEXTURE0 + tex_unit); VL_CHECK_OGL();
01580             VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
01581             #if !defined(NDEBUG)
01582               if ( Has_GLES_Version_1_1 && texarr->glSize() == 1)
01583               {
01584                 Log::error("OpenGL ES does not allow 1D texture coordinates.\n"); VL_TRAP();
01585               }
01586             #endif
01587             glTexCoordPointer((int)texarr->glSize(), texarr->glType(), 0/*texarr->stride()*/, ptr/*+ texarr->offset()*/); VL_CHECK_OGL();
01588 
01589             // enable if not previously enabled
01590             if (mTexCoordArray[tex_unit].mState == 1)
01591             {
01592               glEnableClientState(GL_TEXTURE_COORD_ARRAY); VL_CHECK_OGL();
01593             }
01594             else
01595             {
01596               VL_CHECK(glIsEnabled(GL_TEXTURE_COORD_ARRAY));
01597             }
01598           }
01599         }
01600 
01601         // (2) disable pass
01602         if (mCurVAS)
01603         {
01604           for(int i=0; i<mCurVAS->texCoordArrayCount(); ++i)
01605           {
01606             // texture array info
01607             const ArrayAbstract* texarr = NULL;
01608             int tex_unit = 0;
01609             mCurVAS->getTexCoordArrayAt(i, tex_unit, texarr);
01610             VL_CHECK(tex_unit<VL_MAX_TEXTURE_UNITS);
01611 
01612             // disable if not used by new VAS
01613             if ( mTexCoordArray[tex_unit].mState == 1 )
01614             {
01615               VL_glClientActiveTexture(GL_TEXTURE0 + tex_unit); VL_CHECK_OGL();
01616               glDisableClientState(GL_TEXTURE_COORD_ARRAY); VL_CHECK_OGL();
01617 
01618               mTexCoordArray[tex_unit].mPtr = 0;
01619               mTexCoordArray[tex_unit].mBufferObject = 0;
01620             }
01621 
01622             mTexCoordArray[tex_unit].mState >>= 1; // 1 -> 0; 2 -> 1;
01623           }
01624         }
01625 
01626       } // Has_Fixed_Function_Pipeline
01627 
01628       // ----- vertex attrib -----
01629 
01630       // (1) enable pass
01631       for(int i=0; i<vas->vertexAttribArrays()->size(); ++i)
01632       {
01633         const VertexAttribInfo* info = vas->vertexAttribArrays()->at(i);
01634         int idx = info->attribLocation();
01635 
01636         mVertexAttrib[idx].mState += 1; // 0 -> 1; 1 -> 2;
01637         VL_CHECK( mVertexAttrib[idx].mState == 1 || mVertexAttrib[idx].mState == 2 );
01638 
01639         if ( use_bo && info->data()->bufferObject()->handle() )
01640         {
01641           buf_obj = info->data()->bufferObject()->handle();
01642           ptr = 0;
01643         }
01644         else
01645         {
01646           buf_obj = 0;
01647           ptr = info->data()->bufferObject()->ptr();
01648         }
01649         if ( mVertexAttrib[idx].mPtr != ptr || mVertexAttrib[idx].mBufferObject != buf_obj )
01650         {
01651           mVertexAttrib[idx].mPtr = ptr;
01652           mVertexAttrib[idx].mBufferObject = buf_obj;
01653           VL_glBindBuffer(GL_ARRAY_BUFFER, buf_obj); VL_CHECK_OGL();
01654 
01655           if ( info->interpretation() == VAI_NORMAL )
01656           {
01657             VL_glVertexAttribPointer( idx, (int)info->data()->glSize(), info->data()->glType(), info->normalize(), /*stride*/0, ptr ); VL_CHECK_OGL();
01658           }
01659           else
01660           if ( info->interpretation() == VAI_INTEGER )
01661           {
01662             VL_glVertexAttribIPointer( idx, (int)info->data()->glSize(), info->data()->glType(), /*stride*/0, ptr ); VL_CHECK_OGL();
01663           }
01664           else
01665           if ( info->interpretation() == VAI_DOUBLE )
01666           {
01667             VL_glVertexAttribLPointer( idx, (int)info->data()->glSize(), info->data()->glType(), /*stride*/0, ptr ); VL_CHECK_OGL();
01668           }
01669 
01670           // enable if not previously enabled
01671           if (mVertexAttrib[idx].mState == 1)
01672           {
01673             VL_glEnableVertexAttribArray( idx ); VL_CHECK_OGL();
01674           }
01675           else
01676           {
01677             // make sure it is actually enabled
01678             #if !defined(NDEBUG)
01679               GLint enabled = 0;
01680               glGetVertexAttribiv( idx, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled); VL_CHECK(enabled);
01681             #endif
01682           }
01683         }
01684       }
01685 
01686       // (2) disable pass
01687       if (mCurVAS)
01688       {
01689         for(int i=0; i<mCurVAS->vertexAttribArrays()->size(); ++i)
01690         {
01691           // vertex array
01692           const VertexAttribInfo* info = mCurVAS->vertexAttribArrays()->at(i);
01693           VL_CHECK(info)
01694           int idx = info->attribLocation();
01695           // disable if not used by new VAS
01696           if ( mVertexAttrib[idx].mState == 1 )
01697           {
01698             VL_glDisableVertexAttribArray( idx ); VL_CHECK_OGL();
01699 
01700             // restore constant vertex attrib
01701             glVertexAttrib4fv( idx, mVertexAttribValue[idx].ptr() ); VL_CHECK_OGL();
01702 
01703             mVertexAttrib[idx].mPtr = 0;
01704             mVertexAttrib[idx].mBufferObject = 0;
01705           }
01706 
01707           mVertexAttrib[idx].mState >>= 1; // 1 -> 0; 2 -> 1;
01708         }
01709       }
01710 
01711       // ----- end -----
01712 
01713       // Note: we don't call "glBindBuffer(GL_ARRAY_BUFFER, 0)" here as it will be called by Renderer::render() just before exiting.
01714       // VL_glBindBuffer(GL_ARRAY_BUFFER, 0); VL_CHECK_OGL();
01715 
01716     } // if(vas)
01717 
01718   } // if(vas != mCurVAS || force)
01719 
01720   mCurVAS = vas;
01721 
01722   VL_CHECK_OGL();
01723 }
01724 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:38.
Permission is granted to use this page to write and publish articles regarding Visualization Library.