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