494 lines
17 KiB
C++
494 lines
17 KiB
C++
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======//
|
|
//
|
|
// glentrypoints.cpp
|
|
//
|
|
//=============================================================================//
|
|
// Immediately include gl.h, etc. here to avoid compilation warnings.
|
|
|
|
#include "togl/rendermechanism.h"
|
|
|
|
#include "appframework/AppFramework.h"
|
|
#include "appframework/IAppSystemGroup.h"
|
|
#include "tier0/dbg.h"
|
|
#include "tier0/icommandline.h"
|
|
#include "tier0/dynfunction.h"
|
|
#include "interface.h"
|
|
#include "filesystem.h"
|
|
#include "filesystem_init.h"
|
|
#include "tier1/convar.h"
|
|
#include "vstdlib/cvar.h"
|
|
#include "inputsystem/ButtonCode.h"
|
|
#include "tier1.h"
|
|
#include "tier2/tier2.h"
|
|
|
|
#ifdef _LINUX
|
|
#include <GL/glx.h>
|
|
#endif
|
|
// NOTE: This has to be the last file included!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#if !defined(DX_TO_GL_ABSTRACTION)
|
|
#error
|
|
#endif
|
|
|
|
#if defined( USE_SDL ) || defined(OSX)
|
|
#include "appframework/ilaunchermgr.h"
|
|
ILauncherMgr *g_pLauncherMgr = NULL;
|
|
#endif
|
|
|
|
#define DEBUG_ALL_GLCALLS 0
|
|
|
|
#if DEBUG_ALL_GLCALLS
|
|
bool g_bDebugOpenGLCalls = true;
|
|
bool g_bPrintOpenGLCalls = false;
|
|
|
|
#define GL_EXT(x,glmajor,glminor)
|
|
#define GL_FUNC(ext,req,ret,fn,arg,call) \
|
|
static ret (*fn##_gldebugptr) arg = NULL; \
|
|
static ret fn##_gldebug arg { \
|
|
if (!g_bDebugOpenGLCalls) { return fn##_gldebugptr call; } \
|
|
if (g_bPrintOpenGLCalls) { \
|
|
printf("Calling %s ... ", #fn); \
|
|
fflush(stdout); \
|
|
} \
|
|
ret retval = fn##_gldebugptr call; \
|
|
if (g_bPrintOpenGLCalls) { \
|
|
printf("%s returned!\n", #fn); \
|
|
fflush(stdout); \
|
|
} \
|
|
const GLenum err = glGetError_gldebugptr(); \
|
|
if ( err == GL_INVALID_FRAMEBUFFER_OPERATION_EXT ) { \
|
|
const GLenum fberr = gGL->glCheckFramebufferStatus( GL_FRAMEBUFFER_EXT ); \
|
|
printf("%s triggered error GL_INVALID_FRAMEBUFFER_OPERATION_EXT! (0x%X)\n\n\n", #fn, (int) fberr); \
|
|
fflush(stdout); \
|
|
__asm__ __volatile__ ( "int $3\n\t" ); \
|
|
} else if (err != GL_NO_ERROR) { \
|
|
printf("%s triggered error 0x%X!\n\n\n", #fn, (int) err); \
|
|
fflush(stdout); \
|
|
__asm__ __volatile__ ( "int $3\n\t" ); \
|
|
} \
|
|
return retval; \
|
|
}
|
|
|
|
#define GL_FUNC_VOID(ext,req,fn,arg,call) \
|
|
static void (*fn##_gldebugptr) arg = NULL; \
|
|
static void fn##_gldebug arg { \
|
|
if (!g_bDebugOpenGLCalls) { fn##_gldebugptr call; return; } \
|
|
if (g_bPrintOpenGLCalls) { \
|
|
printf("Calling %s ... ", #fn); \
|
|
fflush(stdout); \
|
|
} \
|
|
fn##_gldebugptr call; \
|
|
if (g_bPrintOpenGLCalls) { \
|
|
printf("%s returned!\n", #fn); \
|
|
fflush(stdout); \
|
|
} \
|
|
const GLenum err = glGetError_gldebugptr(); \
|
|
if ( err == GL_INVALID_FRAMEBUFFER_OPERATION_EXT ) { \
|
|
const GLenum fberr = gGL->glCheckFramebufferStatus( GL_FRAMEBUFFER_EXT ); \
|
|
printf("%s triggered error GL_INVALID_FRAMEBUFFER_OPERATION_EXT! (0x%X)\n\n\n", #fn, (int) fberr); \
|
|
fflush(stdout); \
|
|
__asm__ __volatile__ ( "int $3\n\t" ); \
|
|
} else if (err != GL_NO_ERROR) { \
|
|
printf("%s triggered error 0x%X!\n\n\n", #fn, (int) err); \
|
|
fflush(stdout); \
|
|
__asm__ __volatile__ ( "int $3\n\t" ); \
|
|
} \
|
|
}
|
|
|
|
#include "togl/glfuncs.inl"
|
|
#undef GL_FUNC_VOID
|
|
#undef GL_FUNC
|
|
#undef GL_EXT
|
|
#endif
|
|
|
|
COpenGLEntryPoints *gGL = NULL;
|
|
GL_GetProcAddressCallbackFunc_t gGL_GetProcAddressCallback = NULL;
|
|
|
|
void *VoidFnPtrLookup_GlMgr( const char *libname, const char *fn, bool &okay, const bool bRequired, void *fallback)
|
|
{
|
|
void *retval = NULL;
|
|
if ((!okay) && (!bRequired)) // always look up if required (so we get a complete list of crucial missing symbols).
|
|
return NULL;
|
|
// The SDL path would work on all these platforms, if we were using SDL there, too...
|
|
#if defined( LINUX ) || defined( WIN32 )
|
|
// SDL does the right thing, so we never need to use tier0 in this case.
|
|
retval = (*gGL_GetProcAddressCallback)( libname, fn, okay, bRequired, fallback); //SDL_GL_GetProcAddress(fn);
|
|
//printf("CDynamicFunctionOpenGL: SDL_GL_GetProcAddress(\"%s\") returned %p\n", fn, retval);
|
|
if ((retval == NULL) && (fallback != NULL))
|
|
{
|
|
//printf("CDynamicFunctionOpenGL: Using fallback %p for \"%s\"\n", fallback, fn);
|
|
retval = fallback;
|
|
}
|
|
#elif defined OSX
|
|
// there's no glXGetProcAddress() equivalent for Mac OS X...it's just dlopen(), basically. Let tier0 handle that.
|
|
retval = VoidFnPtrLookup_Tier0( libname, fn, (void *) fallback);
|
|
#endif
|
|
|
|
// Note that a non-NULL response doesn't mean it's safe to call the function!
|
|
// You always have to check that the extension is supported;
|
|
// an implementation MAY return NULL in this case, but it doesn't have to (and doesn't, with the DRI drivers).
|
|
okay = (okay && (retval != NULL));
|
|
if (bRequired && !okay)
|
|
fprintf(stderr, "Could not find required OpenGL entry point '%s'!\n", fn);
|
|
|
|
return retval;
|
|
}
|
|
|
|
COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback)
|
|
{
|
|
if (gGL == NULL)
|
|
{
|
|
gGL_GetProcAddressCallback = callback;
|
|
gGL = new COpenGLEntryPoints(LIBGL_SONAME);
|
|
if (!gGL->m_bHave_OpenGL)
|
|
Error( "Missing basic required OpenGL functionality. %s", LIBGL_SONAME );
|
|
}
|
|
return gGL;
|
|
}
|
|
|
|
void ClearOpenGLEntryPoints()
|
|
{
|
|
if ( gGL )
|
|
{
|
|
gGL->ClearEntryPoints();
|
|
}
|
|
}
|
|
COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory )
|
|
{
|
|
ConnectTier1Libraries( &factory, 1 );
|
|
ConVar_Register();
|
|
ConnectTier2Libraries( &factory, 1 );
|
|
|
|
if ( !g_pFullFileSystem )
|
|
{
|
|
Warning( "ToGL was unable to access the required interfaces!\n" );
|
|
}
|
|
|
|
// NOTE! : Overbright is 1.0 so that Hammer will work properly with the white bumped and unbumped lightmaps.
|
|
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
|
|
|
|
#if defined( USE_SDL )
|
|
g_pLauncherMgr = (ILauncherMgr *)factory( SDLMGR_INTERFACE_VERSION, NULL );
|
|
#elif defined( OSX )
|
|
g_pLauncherMgr = (ILauncherMgr *)factory( COCOAMGR_INTERFACE_VERSION, NULL );
|
|
#endif
|
|
|
|
return gGL;
|
|
}
|
|
|
|
void ToGLDisconnectLibraries()
|
|
{
|
|
DisconnectTier2Libraries();
|
|
ConVar_Unregister();
|
|
DisconnectTier1Libraries();
|
|
}
|
|
|
|
#define GLVERNUM(Major, Minor, Patch) (((Major) * 100000) + ((Minor) * 1000) + (Patch))
|
|
|
|
static void GetOpenGLVersion( const char *libname, int *major, int *minor, int *patch)
|
|
{
|
|
*major = *minor = *patch = 0;
|
|
static CDynamicFunctionOpenGL< true, const GLubyte *( APIENTRY *)(GLenum name), const GLubyte * > glGetString( libname, "glGetString");
|
|
if (glGetString)
|
|
{
|
|
const char *version = (const char *) glGetString(GL_VERSION);
|
|
if (version)
|
|
{
|
|
sscanf( version, "%d.%d.%d", major, minor, patch );
|
|
}
|
|
}
|
|
}
|
|
|
|
static int GetOpenGLVersionMajor(const char *libname)
|
|
{
|
|
int major, minor, patch;
|
|
GetOpenGLVersion(libname, &major, &minor, &patch);
|
|
return major;
|
|
}
|
|
|
|
static int GetOpenGLVersionMinor(const char *libname)
|
|
{
|
|
int major, minor, patch;
|
|
GetOpenGLVersion(libname, &major, &minor, &patch);
|
|
return minor;
|
|
}
|
|
|
|
static int GetOpenGLVersionPatch(const char *libname)
|
|
{
|
|
int major, minor, patch;
|
|
GetOpenGLVersion(libname, &major, &minor, &patch);
|
|
return patch;
|
|
}
|
|
|
|
static bool CheckBaseOpenGLVersion(const char *libname)
|
|
{
|
|
const int NEED_MAJOR = 2;
|
|
const int NEED_MINOR = 0;
|
|
const int NEED_PATCH = 0;
|
|
|
|
int major, minor, patch;
|
|
GetOpenGLVersion(libname, &major, &minor, &patch);
|
|
|
|
const int need = GLVERNUM(NEED_MAJOR, NEED_MINOR, NEED_PATCH);
|
|
const int have = GLVERNUM(major, minor, patch);
|
|
if (have < need)
|
|
{
|
|
fprintf(stderr, "PROBLEM: You appear to have OpenGL %d.%d.%d, but we need at least %d.%d.%d!\n",
|
|
major, minor, patch, NEED_MAJOR, NEED_MINOR, NEED_PATCH);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool CheckOpenGLExtension_internal(const char *libname, const char *ext, const int coremajor, const int coreminor)
|
|
{
|
|
if ((coremajor >= 0) && (coreminor >= 0)) // we know that this extension is part of the base spec as of GL_VERSION coremajor.coreminor.
|
|
{
|
|
int major, minor, patch;
|
|
GetOpenGLVersion(libname, &major, &minor, &patch);
|
|
const int need = GLVERNUM(coremajor, coreminor, 0);
|
|
const int have = GLVERNUM(major, minor, patch);
|
|
if (have >= need)
|
|
return true; // we definitely have access to this "extension," as it is part of this version of the GL's core functionality.
|
|
}
|
|
|
|
// okay, see if the GL_EXTENSIONS string reports it.
|
|
static CDynamicFunctionOpenGL< true, const GLubyte *( APIENTRY *)(GLenum name), const GLubyte * > glGetString(libname, "glGetString");
|
|
if (!glGetString)
|
|
return false;
|
|
|
|
// hacky scanning of this string, because I don't want to spend time breaking it into a vector like I should have.
|
|
const char *extensions = (const char *) glGetString(GL_EXTENSIONS);
|
|
const size_t extlen = strlen(ext);
|
|
while ((extensions) && (*extensions))
|
|
{
|
|
const char *ptr = strstr(extensions, ext);
|
|
#if _WIN32
|
|
if (!ptr)
|
|
{
|
|
static CDynamicFunctionOpenGL< true, const char *( APIENTRY *)( ), const char * > wglGetExtensionsStringEXT(NULL, "wglGetExtensionsStringEXT");
|
|
if (wglGetExtensionsStringEXT)
|
|
{
|
|
extensions = wglGetExtensionsStringEXT();
|
|
ptr = strstr(extensions, ext);
|
|
}
|
|
|
|
if (!ptr)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
#elif defined (OSX)
|
|
if (!ptr)
|
|
return false; // definitely not there.
|
|
#else
|
|
if (!ptr)
|
|
{
|
|
static CDynamicFunctionOpenGL< true, Display *( APIENTRY *)( ), Display* > glXGetCurrentDisplay( NULL, "glXGetCurrentDisplay");
|
|
static CDynamicFunctionOpenGL< true, const char *( APIENTRY *)( Display*, int ), const char * > glXQueryExtensionsString( NULL, "glXQueryExtensionsString");
|
|
if (glXQueryExtensionsString && glXGetCurrentDisplay)
|
|
{
|
|
extensions = glXQueryExtensionsString(glXGetCurrentDisplay(), 0);
|
|
ptr = strstr(extensions, ext);
|
|
}
|
|
|
|
if (!ptr)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// make sure this matches the entire string, and isn't a substring match of some other extension.
|
|
// if ( ( (string is at start of extension list) or (the char before the string is a space) ) and
|
|
// (the next char after the string is a space or a null terminator) )
|
|
if ( ((ptr == extensions) || (ptr[-1] == ' ')) &&
|
|
((ptr[extlen] == ' ') || (ptr[extlen] == '\0')) )
|
|
return true; // found it!
|
|
|
|
extensions = ptr + extlen; // skip ahead, search again.
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool CheckOpenGLExtension(const char *libname, const char *ext, const int coremajor, const int coreminor)
|
|
{
|
|
const bool retval = CheckOpenGLExtension_internal(libname, ext, coremajor, coreminor);
|
|
printf("This system %s the OpenGL extension %s.\n", retval ? "supports" : "DOES NOT support", ext);
|
|
return retval;
|
|
}
|
|
|
|
// The GL context you want entry points for must be current when you hit this constructor!
|
|
COpenGLEntryPoints::COpenGLEntryPoints(const char *libname)
|
|
: m_nTotalGLCycles(0)
|
|
, m_nTotalGLCalls(0)
|
|
, m_strLibName(libname)
|
|
, m_nOpenGLVersionMajor(GetOpenGLVersionMajor(m_strLibName))
|
|
, m_nOpenGLVersionMinor(GetOpenGLVersionMinor(m_strLibName))
|
|
, m_nOpenGLVersionPatch(GetOpenGLVersionPatch(m_strLibName))
|
|
, m_bHave_OpenGL(CheckBaseOpenGLVersion(m_strLibName)) // may reset to false as these lookups happen.
|
|
#define GL_EXT(x,glmajor,glminor) , m_bHave_##x(CheckOpenGLExtension(m_strLibName, #x, glmajor, glminor))
|
|
#define GL_FUNC(ext,req,ret,fn,arg,call) , fn(m_strLibName, #fn, m_bHave_##ext)
|
|
#define GL_FUNC_VOID(ext,req,fn,arg,call) , fn(m_strLibName, #fn, m_bHave_##ext)
|
|
#include "togl/glfuncs.inl"
|
|
#undef GL_FUNC_VOID
|
|
#undef GL_FUNC
|
|
#undef GL_EXT
|
|
{
|
|
// 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.
|
|
const char *pszString = ( const char * )glGetString(GL_VENDOR);
|
|
m_pGLDriverStrings[cGLVendorString] = strdup( pszString ? pszString : "" );
|
|
|
|
m_nDriverProvider = cGLDriverProviderUnknown;
|
|
if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "nvidia" ) )
|
|
m_nDriverProvider = cGLDriverProviderNVIDIA;
|
|
else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "amd" ) || V_stristr( m_pGLDriverStrings[cGLVendorString], "ati" ) )
|
|
m_nDriverProvider = cGLDriverProviderAMD;
|
|
else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "intel" ) )
|
|
m_nDriverProvider = cGLDriverProviderIntelOpenSource;
|
|
else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "apple" ) )
|
|
m_nDriverProvider = cGLDriverProviderApple;
|
|
|
|
pszString = ( const char * )glGetString(GL_RENDERER);
|
|
m_pGLDriverStrings[cGLRendererString] = strdup( pszString ? pszString : "" );
|
|
|
|
pszString = ( const char * )glGetString(GL_VERSION);
|
|
m_pGLDriverStrings[cGLVersionString] = strdup( pszString ? pszString : "" );
|
|
|
|
pszString = ( const char * )glGetString(GL_EXTENSIONS);
|
|
m_pGLDriverStrings[cGLExtensionsString] = strdup( pszString ? pszString : "" );
|
|
|
|
// !!! FIXME: Alfred says the original GL_APPLE_fence code only exists to
|
|
// !!! FIXME: hint Apple's drivers and not because we rely on the
|
|
// !!! FIXME: functionality. If so, just remove this check (and the
|
|
// !!! FIXME: GL_NV_fence code entirely).
|
|
if ((m_bHave_OpenGL) && ((!m_bHave_GL_NV_fence) && (!m_bHave_GL_ARB_sync) && (!m_bHave_GL_APPLE_fence)))
|
|
{
|
|
Error( "Required OpenGL extension \"GL_NV_fence\", \"GL_ARB_sync\", or \"GL_APPLE_fence\" is not supported. Please upgrade your OpenGL driver." );
|
|
}
|
|
|
|
// same extension, different name.
|
|
if (m_bHave_GL_EXT_vertex_array_bgra || m_bHave_GL_ARB_vertex_array_bgra)
|
|
{
|
|
m_bHave_GL_EXT_vertex_array_bgra = m_bHave_GL_ARB_vertex_array_bgra = true;
|
|
}
|
|
|
|
// GL_ARB_framebuffer_object is a superset of GL_EXT_framebuffer_object,
|
|
// (etc) but if you don't call in through the ARB entry points, you won't
|
|
// get the relaxed restrictions on mismatched attachment dimensions.
|
|
if (m_bHave_GL_ARB_framebuffer_object)
|
|
{
|
|
m_bHave_GL_EXT_framebuffer_object = true;
|
|
m_bHave_GL_EXT_framebuffer_blit = true;
|
|
m_bHave_GL_EXT_framebuffer_multisample = true;
|
|
glBindFramebufferEXT.Force(glBindFramebuffer.Pointer());
|
|
glBindRenderbufferEXT.Force(glBindRenderbuffer.Pointer());
|
|
glCheckFramebufferStatusEXT.Force(glCheckFramebufferStatus.Pointer());
|
|
glDeleteRenderbuffersEXT.Force(glDeleteRenderbuffers.Pointer());
|
|
glFramebufferRenderbufferEXT.Force(glFramebufferRenderbuffer.Pointer());
|
|
glFramebufferTexture2DEXT.Force(glFramebufferTexture2D.Pointer());
|
|
glFramebufferTexture3DEXT.Force(glFramebufferTexture3D.Pointer());
|
|
glGenFramebuffersEXT.Force(glGenFramebuffers.Pointer());
|
|
glGenRenderbuffersEXT.Force(glGenRenderbuffers.Pointer());
|
|
glDeleteFramebuffersEXT.Force(glDeleteFramebuffers.Pointer());
|
|
glBlitFramebufferEXT.Force(glBlitFramebuffer.Pointer());
|
|
glRenderbufferStorageMultisampleEXT.Force(glRenderbufferStorageMultisample.Pointer());
|
|
}
|
|
|
|
#if DEBUG_ALL_GLCALLS
|
|
// push all GL calls through the debug wrappers.
|
|
#define GL_EXT(x,glmajor,glminor)
|
|
#define GL_FUNC(ext,req,ret,fn,arg,call) \
|
|
fn##_gldebugptr = this->fn; \
|
|
this->fn.Force(fn##_gldebug);
|
|
#define GL_FUNC_VOID(ext,req,fn,arg,call) \
|
|
fn##_gldebugptr = this->fn; \
|
|
this->fn.Force(fn##_gldebug);
|
|
#include "togl/glfuncs.inl"
|
|
#undef GL_FUNC_VOID
|
|
#undef GL_FUNC
|
|
#undef GL_EXT
|
|
#endif
|
|
|
|
#ifdef OSX
|
|
m_bHave_GL_NV_bindless_texture = false;
|
|
m_bHave_GL_AMD_pinned_memory = false;
|
|
#else
|
|
if ( ( m_bHave_GL_NV_bindless_texture ) && ( !CommandLine()->CheckParm( "-gl_nv_bindless_texturing" ) ) )
|
|
{
|
|
m_bHave_GL_NV_bindless_texture = false;
|
|
glGetTextureHandleNV.Force( NULL );
|
|
glGetTextureSamplerHandleNV.Force( NULL );
|
|
glMakeTextureHandleResidentNV.Force( NULL );
|
|
glMakeTextureHandleNonResidentNV.Force( NULL );
|
|
glUniformHandleui64NV.Force( NULL );
|
|
glUniformHandleui64vNV.Force( NULL );
|
|
glProgramUniformHandleui64NV.Force( NULL );
|
|
glProgramUniformHandleui64vNV.Force( NULL );
|
|
glIsTextureHandleResidentNV.Force( NULL );
|
|
}
|
|
|
|
if ( ( m_bHave_GL_AMD_pinned_memory ) && ( !CommandLine()->CheckParm( "-gl_amd_pinned_memory" ) ) )
|
|
{
|
|
m_bHave_GL_AMD_pinned_memory = false;
|
|
}
|
|
#endif
|
|
|
|
if ( ( m_bHave_GL_ARB_buffer_storage ) && ( CommandLine()->CheckParm( "-gl_disable_arb_buffer_storage" ) ) )
|
|
{
|
|
m_bHave_GL_ARB_buffer_storage = false;
|
|
}
|
|
|
|
char buf[256];
|
|
V_snprintf(buf, sizeof( buf ), "GL_NV_bindless_texture: %s\n", m_bHave_GL_NV_bindless_texture ? "ENABLED" : "DISABLED" );
|
|
Plat_DebugString( buf );
|
|
|
|
V_snprintf(buf, sizeof( buf ), "GL_AMD_pinned_memory: %s\n", m_bHave_GL_AMD_pinned_memory ? "ENABLED" : "DISABLED" );
|
|
Plat_DebugString( buf );
|
|
|
|
V_snprintf( buf, sizeof(buf), "GL_ARB_buffer_storage: %s\n", m_bHave_GL_ARB_buffer_storage ? "AVAILABLE" : "NOT AVAILABLE" );
|
|
Plat_DebugString( buf );
|
|
|
|
V_snprintf(buf, sizeof( buf ), "GL_EXT_texture_sRGB_decode: %s\n", m_bHave_GL_EXT_texture_sRGB_decode ? "AVAILABLE" : "NOT AVAILABLE" );
|
|
Plat_DebugString( buf );
|
|
|
|
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 );
|
|
if ( !bGLCanDecodeS3TCTextures )
|
|
{
|
|
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" );
|
|
}
|
|
|
|
#ifndef OSX
|
|
if ( !m_bHave_GL_EXT_texture_sRGB_decode )
|
|
{
|
|
Error( "Required OpenGL extension \"GL_EXT_texture_sRGB_decode\" is not supported. Please update your OpenGL driver.\n" );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
COpenGLEntryPoints::~COpenGLEntryPoints()
|
|
{
|
|
for ( uint i = 0; i < cGLTotalDriverProviders; ++i )
|
|
{
|
|
free( m_pGLDriverStrings[i] );
|
|
m_pGLDriverStrings[i] = NULL;
|
|
}
|
|
}
|
|
|
|
void COpenGLEntryPoints::ClearEntryPoints()
|
|
{
|
|
#define GL_EXT(x,glmajor,glminor)
|
|
#define GL_FUNC(ext,req,ret,fn,arg,call) fn.Force( NULL );
|
|
#define GL_FUNC_VOID(ext,req,fn,arg,call) fn.Force( NULL );
|
|
#include "togl/glfuncs.inl"
|
|
#undef GL_FUNC_VOID
|
|
#undef GL_FUNC
|
|
#undef GL_EXT
|
|
}
|
|
// Turn off memdbg macros (turned on up top) since this is included like a header
|
|
#include "tier0/memdbgoff.h"
|
|
|
|
|
|
|