# Visualization Library

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

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

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

Visualization Library v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:40.
Permission is granted to use this page to write and publish articles regarding Visualization Library.