# Visualization Library

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

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

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

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:24.
Permission is granted to use this page to write and publish articles regarding Visualization Library.