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