Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

510 lines
18 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // TOGL CODE LICENSE
  3. //
  4. // Copyright 2011-2014 Valve Corporation
  5. // All Rights Reserved.
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. //
  25. // glentrypoints.cpp
  26. //
  27. //=============================================================================//
  28. // Immediately include gl.h, etc. here to avoid compilation warnings.
  29. #include "togl/rendermechanism.h"
  30. #include "appframework/AppFramework.h"
  31. #include "appframework/IAppSystemGroup.h"
  32. #include "tier0/dbg.h"
  33. #include "tier0/icommandline.h"
  34. #include "tier0/platform.h"
  35. #include "interface.h"
  36. #include "filesystem.h"
  37. #include "filesystem_init.h"
  38. #include "tier1/convar.h"
  39. #include "vstdlib/cvar.h"
  40. #include "inputsystem/ButtonCode.h"
  41. #include "tier1.h"
  42. #include "tier2/tier2.h"
  43. #ifdef _LINUX
  44. #include <GL/glx.h>
  45. #endif
  46. // NOTE: This has to be the last file included!
  47. #include "tier0/memdbgon.h"
  48. #if !defined(DX_TO_GL_ABSTRACTION)
  49. #error
  50. #endif
  51. #if defined(OSX) || defined(LINUX) || (defined (WIN32) && defined( DX_TO_GL_ABSTRACTION ))
  52. #include "appframework/ilaunchermgr.h"
  53. ILauncherMgr *g_pLauncherMgr = NULL;
  54. #endif
  55. #define DEBUG_ALL_GLCALLS 0
  56. #if DEBUG_ALL_GLCALLS
  57. bool g_bDebugOpenGLCalls = true;
  58. bool g_bPrintOpenGLCalls = false;
  59. #define GL_EXT(x,glmajor,glminor)
  60. #define GL_FUNC(ext,req,ret,fn,arg,call) \
  61. static ret (*fn##_gldebugptr) arg = NULL; \
  62. static ret fn##_gldebug arg { \
  63. if (!g_bDebugOpenGLCalls) { return fn##_gldebugptr call; } \
  64. if (g_bPrintOpenGLCalls) { \
  65. printf("Calling %s ... ", #fn); \
  66. fflush(stdout); \
  67. } \
  68. ret retval = fn##_gldebugptr call; \
  69. if (g_bPrintOpenGLCalls) { \
  70. printf("%s returned!\n", #fn); \
  71. fflush(stdout); \
  72. } \
  73. const GLenum err = glGetError_gldebugptr(); \
  74. if ( err == GL_INVALID_FRAMEBUFFER_OPERATION_EXT ) { \
  75. const GLenum fberr = gGL->glCheckFramebufferStatus( GL_FRAMEBUFFER_EXT ); \
  76. printf("%s triggered error GL_INVALID_FRAMEBUFFER_OPERATION_EXT! (0x%X)\n\n\n", #fn, (int) fberr); \
  77. fflush(stdout); \
  78. __asm__ __volatile__ ( "int $3\n\t" ); \
  79. } else if (err != GL_NO_ERROR) { \
  80. printf("%s triggered error 0x%X!\n\n\n", #fn, (int) err); \
  81. fflush(stdout); \
  82. __asm__ __volatile__ ( "int $3\n\t" ); \
  83. } \
  84. return retval; \
  85. }
  86. #define GL_FUNC_VOID(ext,req,fn,arg,call) \
  87. static void (*fn##_gldebugptr) arg = NULL; \
  88. static void fn##_gldebug arg { \
  89. if (!g_bDebugOpenGLCalls) { fn##_gldebugptr call; return; } \
  90. if (g_bPrintOpenGLCalls) { \
  91. printf("Calling %s ... ", #fn); \
  92. fflush(stdout); \
  93. } \
  94. fn##_gldebugptr call; \
  95. if (g_bPrintOpenGLCalls) { \
  96. printf("%s returned!\n", #fn); \
  97. fflush(stdout); \
  98. } \
  99. const GLenum err = glGetError_gldebugptr(); \
  100. if ( err == GL_INVALID_FRAMEBUFFER_OPERATION_EXT ) { \
  101. const GLenum fberr = gGL->glCheckFramebufferStatus( GL_FRAMEBUFFER_EXT ); \
  102. printf("%s triggered error GL_INVALID_FRAMEBUFFER_OPERATION_EXT! (0x%X)\n\n\n", #fn, (int) fberr); \
  103. fflush(stdout); \
  104. __asm__ __volatile__ ( "int $3\n\t" ); \
  105. } else if (err != GL_NO_ERROR) { \
  106. printf("%s triggered error 0x%X!\n\n\n", #fn, (int) err); \
  107. fflush(stdout); \
  108. __asm__ __volatile__ ( "int $3\n\t" ); \
  109. } \
  110. }
  111. #include "togl/glfuncs.inl"
  112. #undef GL_FUNC_VOID
  113. #undef GL_FUNC
  114. #undef GL_EXT
  115. #endif
  116. COpenGLEntryPoints *gGL = NULL;
  117. GL_GetProcAddressCallbackFunc_t gGL_GetProcAddressCallback = NULL;
  118. void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback)
  119. {
  120. void *retval = NULL;
  121. if ((!okay) && (!bRequired)) // always look up if required (so we get a complete list of crucial missing symbols).
  122. return NULL;
  123. // SDL does the right thing, so we never need to use tier0 in this case.
  124. retval = (*gGL_GetProcAddressCallback)(fn, okay, bRequired, fallback);
  125. //printf("CDynamicFunctionOpenGL: SDL_GL_GetProcAddress(\"%s\") returned %p\n", fn, retval);
  126. if ((retval == NULL) && (fallback != NULL))
  127. {
  128. //printf("CDynamicFunctionOpenGL: Using fallback %p for \"%s\"\n", fallback, fn);
  129. retval = fallback;
  130. }
  131. // Note that a non-NULL response doesn't mean it's safe to call the function!
  132. // You always have to check that the extension is supported;
  133. // an implementation MAY return NULL in this case, but it doesn't have to (and doesn't, with the DRI drivers).
  134. okay = (okay && (retval != NULL));
  135. if (bRequired && !okay)
  136. fprintf(stderr, "Could not find required OpenGL entry point '%s'!\n", fn);
  137. return retval;
  138. }
  139. COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback)
  140. {
  141. if (gGL == NULL)
  142. {
  143. gGL_GetProcAddressCallback = callback;
  144. gGL = new COpenGLEntryPoints();
  145. if (!gGL->m_bHave_OpenGL)
  146. Error( "Missing basic required OpenGL functionality." );
  147. }
  148. return gGL;
  149. }
  150. void ClearOpenGLEntryPoints()
  151. {
  152. if ( gGL )
  153. {
  154. gGL->ClearEntryPoints();
  155. }
  156. }
  157. COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory )
  158. {
  159. ConnectTier1Libraries( &factory, 1 );
  160. ConVar_Register();
  161. ConnectTier2Libraries( &factory, 1 );
  162. if ( !g_pFullFileSystem )
  163. {
  164. Warning( "ToGL was unable to access the required interfaces!\n" );
  165. }
  166. // NOTE! : Overbright is 1.0 so that Hammer will work properly with the white bumped and unbumped lightmaps.
  167. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
  168. #if defined( USE_SDL )
  169. g_pLauncherMgr = (ILauncherMgr *)factory( SDLMGR_INTERFACE_VERSION, NULL );
  170. #endif
  171. return gGL;
  172. }
  173. void ToGLDisconnectLibraries()
  174. {
  175. DisconnectTier2Libraries();
  176. ConVar_Unregister();
  177. DisconnectTier1Libraries();
  178. }
  179. #define GLVERNUM(Major, Minor, Patch) (((Major) * 100000) + ((Minor) * 1000) + (Patch))
  180. static void GetOpenGLVersion(int *major, int *minor, int *patch)
  181. {
  182. *major = *minor = *patch = 0;
  183. static CDynamicFunctionOpenGL< true, const GLubyte *( APIENTRY *)(GLenum name), const GLubyte * > glGetString("glGetString");
  184. if (glGetString)
  185. {
  186. const char *version = (const char *) glGetString(GL_VERSION);
  187. if (version)
  188. {
  189. sscanf( version, "%d.%d.%d", major, minor, patch );
  190. }
  191. }
  192. }
  193. static int GetOpenGLVersionMajor()
  194. {
  195. int major, minor, patch;
  196. GetOpenGLVersion(&major, &minor, &patch);
  197. return major;
  198. }
  199. static int GetOpenGLVersionMinor()
  200. {
  201. int major, minor, patch;
  202. GetOpenGLVersion(&major, &minor, &patch);
  203. return minor;
  204. }
  205. static int GetOpenGLVersionPatch()
  206. {
  207. int major, minor, patch;
  208. GetOpenGLVersion(&major, &minor, &patch);
  209. return patch;
  210. }
  211. static bool CheckBaseOpenGLVersion()
  212. {
  213. const int NEED_MAJOR = 2;
  214. const int NEED_MINOR = 0;
  215. const int NEED_PATCH = 0;
  216. int major, minor, patch;
  217. GetOpenGLVersion(&major, &minor, &patch);
  218. const int need = GLVERNUM(NEED_MAJOR, NEED_MINOR, NEED_PATCH);
  219. const int have = GLVERNUM(major, minor, patch);
  220. if (have < need)
  221. {
  222. fprintf(stderr, "PROBLEM: You appear to have OpenGL %d.%d.%d, but we need at least %d.%d.%d!\n",
  223. major, minor, patch, NEED_MAJOR, NEED_MINOR, NEED_PATCH);
  224. return false;
  225. }
  226. return true;
  227. }
  228. static bool CheckOpenGLExtension_internal(const char *ext, const int coremajor, const int coreminor)
  229. {
  230. if ((coremajor >= 0) && (coreminor >= 0)) // we know that this extension is part of the base spec as of GL_VERSION coremajor.coreminor.
  231. {
  232. int major, minor, patch;
  233. GetOpenGLVersion(&major, &minor, &patch);
  234. const int need = GLVERNUM(coremajor, coreminor, 0);
  235. const int have = GLVERNUM(major, minor, patch);
  236. if (have >= need)
  237. return true; // we definitely have access to this "extension," as it is part of this version of the GL's core functionality.
  238. }
  239. // okay, see if the GL_EXTENSIONS string reports it.
  240. static CDynamicFunctionOpenGL< true, const GLubyte *( APIENTRY *)(GLenum name), const GLubyte * > glGetString("glGetString");
  241. if (!glGetString)
  242. return false;
  243. // hacky scanning of this string, because I don't want to spend time breaking it into a vector like I should have.
  244. const char *extensions = (const char *) glGetString(GL_EXTENSIONS);
  245. const size_t extlen = strlen(ext);
  246. while ((extensions) && (*extensions))
  247. {
  248. const char *ptr = strstr(extensions, ext);
  249. #if _WIN32
  250. if (!ptr)
  251. {
  252. static CDynamicFunctionOpenGL< true, const char *( APIENTRY *)( ), const char * > wglGetExtensionsStringEXT("wglGetExtensionsStringEXT");
  253. if (wglGetExtensionsStringEXT)
  254. {
  255. extensions = wglGetExtensionsStringEXT();
  256. ptr = strstr(extensions, ext);
  257. }
  258. if (!ptr)
  259. {
  260. return false;
  261. }
  262. }
  263. #elif !defined ( OSX )
  264. if (!ptr)
  265. {
  266. static CDynamicFunctionOpenGL< true, Display *( APIENTRY *)( ), Display* > glXGetCurrentDisplay("glXGetCurrentDisplay");
  267. static CDynamicFunctionOpenGL< true, const char *( APIENTRY *)( Display*, int ), const char * > glXQueryExtensionsString("glXQueryExtensionsString");
  268. if (glXQueryExtensionsString && glXGetCurrentDisplay)
  269. {
  270. extensions = glXQueryExtensionsString(glXGetCurrentDisplay(), 0);
  271. ptr = strstr(extensions, ext);
  272. }
  273. }
  274. #endif
  275. if (!ptr)
  276. return false;
  277. // make sure this matches the entire string, and isn't a substring match of some other extension.
  278. // if ( ( (string is at start of extension list) or (the char before the string is a space) ) and
  279. // (the next char after the string is a space or a null terminator) )
  280. if ( ((ptr == extensions) || (ptr[-1] == ' ')) &&
  281. ((ptr[extlen] == ' ') || (ptr[extlen] == '\0')) )
  282. return true; // found it!
  283. extensions = ptr + extlen; // skip ahead, search again.
  284. }
  285. return false;
  286. }
  287. static bool CheckOpenGLExtension(const char *ext, const int coremajor, const int coreminor)
  288. {
  289. const bool retval = CheckOpenGLExtension_internal(ext, coremajor, coreminor);
  290. printf("This system %s the OpenGL extension %s.\n", retval ? "supports" : "DOES NOT support", ext);
  291. return retval;
  292. }
  293. // The GL context you want entry points for must be current when you hit this constructor!
  294. COpenGLEntryPoints::COpenGLEntryPoints()
  295. : m_nTotalGLCycles(0)
  296. , m_nTotalGLCalls(0)
  297. , m_nOpenGLVersionMajor(GetOpenGLVersionMajor())
  298. , m_nOpenGLVersionMinor(GetOpenGLVersionMinor())
  299. , m_nOpenGLVersionPatch(GetOpenGLVersionPatch())
  300. , m_bHave_OpenGL(CheckBaseOpenGLVersion()) // may reset to false as these lookups happen.
  301. #define GL_EXT(x,glmajor,glminor) , m_bHave_##x(CheckOpenGLExtension(#x, glmajor, glminor))
  302. #define GL_FUNC(ext,req,ret,fn,arg,call) , fn(#fn, m_bHave_##ext)
  303. #define GL_FUNC_VOID(ext,req,fn,arg,call) , fn(#fn, m_bHave_##ext)
  304. #include "togl/glfuncs.inl"
  305. #undef GL_FUNC_VOID
  306. #undef GL_FUNC
  307. #undef GL_EXT
  308. {
  309. // Locally cache the copy of the GL device strings, to avoid needing to call these glGet's (which can be extremely slow) more than once.
  310. const char *pszString = ( const char * )glGetString(GL_VENDOR);
  311. m_pGLDriverStrings[cGLVendorString] = strdup( pszString ? pszString : "" );
  312. m_nDriverProvider = cGLDriverProviderUnknown;
  313. if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "nvidia" ) )
  314. m_nDriverProvider = cGLDriverProviderNVIDIA;
  315. else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "amd" ) || V_stristr( m_pGLDriverStrings[cGLVendorString], "ati" ) )
  316. m_nDriverProvider = cGLDriverProviderAMD;
  317. else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "intel" ) )
  318. m_nDriverProvider = cGLDriverProviderIntelOpenSource;
  319. else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "apple" ) )
  320. m_nDriverProvider = cGLDriverProviderApple;
  321. pszString = ( const char * )glGetString(GL_RENDERER);
  322. m_pGLDriverStrings[cGLRendererString] = strdup( pszString ? pszString : "" );
  323. pszString = ( const char * )glGetString(GL_VERSION);
  324. m_pGLDriverStrings[cGLVersionString] = strdup( pszString ? pszString : "" );
  325. pszString = ( const char * )glGetString(GL_EXTENSIONS);
  326. m_pGLDriverStrings[cGLExtensionsString] = strdup( pszString ? pszString : "" );
  327. printf( "OpenGL: %s %s (%d.%d.%d)\n", m_pGLDriverStrings[ cGLRendererString ], m_pGLDriverStrings[ cGLVersionString ],
  328. m_nOpenGLVersionMajor, m_nOpenGLVersionMinor, m_nOpenGLVersionPatch );
  329. // !!! FIXME: Alfred says the original GL_APPLE_fence code only exists to
  330. // !!! FIXME: hint Apple's drivers and not because we rely on the
  331. // !!! FIXME: functionality. If so, just remove this check (and the
  332. // !!! FIXME: GL_NV_fence code entirely).
  333. if ((m_bHave_OpenGL) && ((!m_bHave_GL_NV_fence) && (!m_bHave_GL_ARB_sync) && (!m_bHave_GL_APPLE_fence)))
  334. {
  335. Error( "Required OpenGL extension \"GL_NV_fence\", \"GL_ARB_sync\", or \"GL_APPLE_fence\" is not supported. Please upgrade your OpenGL driver." );
  336. }
  337. // same extension, different name.
  338. if (m_bHave_GL_EXT_vertex_array_bgra || m_bHave_GL_ARB_vertex_array_bgra)
  339. {
  340. m_bHave_GL_EXT_vertex_array_bgra = m_bHave_GL_ARB_vertex_array_bgra = true;
  341. }
  342. // GL_ARB_framebuffer_object is a superset of GL_EXT_framebuffer_object,
  343. // (etc) but if you don't call in through the ARB entry points, you won't
  344. // get the relaxed restrictions on mismatched attachment dimensions.
  345. if (m_bHave_GL_ARB_framebuffer_object)
  346. {
  347. m_bHave_GL_EXT_framebuffer_object = true;
  348. m_bHave_GL_EXT_framebuffer_blit = true;
  349. m_bHave_GL_EXT_framebuffer_multisample = true;
  350. glBindFramebufferEXT.Force(glBindFramebuffer.Pointer());
  351. glBindRenderbufferEXT.Force(glBindRenderbuffer.Pointer());
  352. glCheckFramebufferStatusEXT.Force(glCheckFramebufferStatus.Pointer());
  353. glDeleteRenderbuffersEXT.Force(glDeleteRenderbuffers.Pointer());
  354. glFramebufferRenderbufferEXT.Force(glFramebufferRenderbuffer.Pointer());
  355. glFramebufferTexture2DEXT.Force(glFramebufferTexture2D.Pointer());
  356. glFramebufferTexture3DEXT.Force(glFramebufferTexture3D.Pointer());
  357. glGenFramebuffersEXT.Force(glGenFramebuffers.Pointer());
  358. glGenRenderbuffersEXT.Force(glGenRenderbuffers.Pointer());
  359. glDeleteFramebuffersEXT.Force(glDeleteFramebuffers.Pointer());
  360. glBlitFramebufferEXT.Force(glBlitFramebuffer.Pointer());
  361. glRenderbufferStorageMultisampleEXT.Force(glRenderbufferStorageMultisample.Pointer());
  362. }
  363. #if DEBUG_ALL_GLCALLS
  364. // push all GL calls through the debug wrappers.
  365. #define GL_EXT(x,glmajor,glminor)
  366. #define GL_FUNC(ext,req,ret,fn,arg,call) \
  367. fn##_gldebugptr = this->fn; \
  368. this->fn.Force(fn##_gldebug);
  369. #define GL_FUNC_VOID(ext,req,fn,arg,call) \
  370. fn##_gldebugptr = this->fn; \
  371. this->fn.Force(fn##_gldebug);
  372. #include "togl/glfuncs.inl"
  373. #undef GL_FUNC_VOID
  374. #undef GL_FUNC
  375. #undef GL_EXT
  376. #endif
  377. #ifdef OSX
  378. m_bHave_GL_NV_bindless_texture = false;
  379. m_bHave_GL_AMD_pinned_memory = false;
  380. #else
  381. if ( ( m_bHave_GL_NV_bindless_texture ) && ( !CommandLine()->CheckParm( "-gl_nv_bindless_texturing" ) ) )
  382. {
  383. m_bHave_GL_NV_bindless_texture = false;
  384. glGetTextureHandleNV.Force( NULL );
  385. glGetTextureSamplerHandleNV.Force( NULL );
  386. glMakeTextureHandleResidentNV.Force( NULL );
  387. glMakeTextureHandleNonResidentNV.Force( NULL );
  388. glUniformHandleui64NV.Force( NULL );
  389. glUniformHandleui64vNV.Force( NULL );
  390. glProgramUniformHandleui64NV.Force( NULL );
  391. glProgramUniformHandleui64vNV.Force( NULL );
  392. glIsTextureHandleResidentNV.Force( NULL );
  393. }
  394. if ( !CommandLine()->CheckParm( "-gl_amd_pinned_memory" ) )
  395. {
  396. m_bHave_GL_AMD_pinned_memory = false;
  397. }
  398. #endif // !OSX
  399. // Getting reports of black screens, etc. with ARB_buffer_storage and AMD drivers. This type of thing:
  400. // http://forums.steampowered.com/forums/showthread.php?t=3266806
  401. // So disable it for now.
  402. if ( ( m_nDriverProvider == cGLDriverProviderAMD ) || CommandLine()->CheckParm( "-gl_disable_arb_buffer_storage" ) )
  403. {
  404. m_bHave_GL_ARB_buffer_storage = false;
  405. }
  406. printf( "GL_NV_bindless_texture: %s\n", m_bHave_GL_NV_bindless_texture ? "ENABLED" : "DISABLED" );
  407. printf( "GL_AMD_pinned_memory: %s\n", m_bHave_GL_AMD_pinned_memory ? "ENABLED" : "DISABLED" );
  408. printf( "GL_ARB_buffer_storage: %s\n", m_bHave_GL_ARB_buffer_storage ? "AVAILABLE" : "NOT AVAILABLE" );
  409. printf( "GL_EXT_texture_sRGB_decode: %s\n", m_bHave_GL_EXT_texture_sRGB_decode ? "AVAILABLE" : "NOT AVAILABLE" );
  410. bool bGLCanDecodeS3TCTextures = m_bHave_GL_EXT_texture_compression_s3tc || ( m_bHave_GL_EXT_texture_compression_dxt1 && m_bHave_GL_ANGLE_texture_compression_dxt3 && m_bHave_GL_ANGLE_texture_compression_dxt5 );
  411. if ( !bGLCanDecodeS3TCTextures )
  412. {
  413. Error( "This application requires either the GL_EXT_texture_compression_s3tc, or the GL_EXT_texture_compression_dxt1 + GL_ANGLE_texture_compression_dxt3 + GL_ANGLE_texture_compression_dxt5 OpenGL extensions. Please install S3TC texture support.\n" );
  414. }
  415. #ifdef OSX
  416. if ( CommandLine()->FindParm( "-glmnosrgbdecode" ) )
  417. {
  418. Msg( "Forcing m_bHave_GL_EXT_texture_sRGB_decode off.\n" );
  419. m_bHave_GL_EXT_texture_sRGB_decode = false;
  420. }
  421. #endif
  422. #ifndef OSX
  423. if ( !m_bHave_GL_EXT_texture_sRGB_decode )
  424. {
  425. Error( "Required OpenGL extension \"GL_EXT_texture_sRGB_decode\" is not supported. Please update your OpenGL driver.\n" );
  426. }
  427. #endif
  428. }
  429. COpenGLEntryPoints::~COpenGLEntryPoints()
  430. {
  431. for ( uint i = 0; i < cGLTotalDriverProviders; ++i )
  432. {
  433. free( m_pGLDriverStrings[i] );
  434. m_pGLDriverStrings[i] = NULL;
  435. }
  436. }
  437. void COpenGLEntryPoints::ClearEntryPoints()
  438. {
  439. #define GL_EXT(x,glmajor,glminor)
  440. #define GL_FUNC(ext,req,ret,fn,arg,call) fn.Force( NULL );
  441. #define GL_FUNC_VOID(ext,req,fn,arg,call) fn.Force( NULL );
  442. #include "togl/glfuncs.inl"
  443. #undef GL_FUNC_VOID
  444. #undef GL_FUNC
  445. #undef GL_EXT
  446. }
  447. // Turn off memdbg macros (turned on up top) since this is included like a header
  448. #include "tier0/memdbgoff.h"