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