Index: trunk/nv/common.hh
===================================================================
--- trunk/nv/common.hh	(revision 310)
+++ trunk/nv/common.hh	(revision 311)
@@ -140,4 +140,7 @@
 #define NV_RETURN_COVERED_DEFAULT( value ) default : return value
 #endif
+
+#define NV_COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
+#define NV_SAFE_ARRAY( arr, idx, def ) ( index < NV_COUNT_OF(arr) ? (arr)[idx] : (def) )
 
 namespace nv
Index: trunk/nv/lib/detail/gl_ext/gl_ext_all_functions.inc
===================================================================
--- trunk/nv/lib/detail/gl_ext/gl_ext_all_functions.inc	(revision 311)
+++ trunk/nv/lib/detail/gl_ext/gl_ext_all_functions.inc	(revision 311)
@@ -0,0 +1,2 @@
+#include <nv/lib/detail/gl_ext/gl_ext_framebuffer_object_functions.inc>
+#include <nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_functions.inc>
Index: trunk/nv/lib/detail/gl_ext/gl_ext_all_types.inc
===================================================================
--- trunk/nv/lib/detail/gl_ext/gl_ext_all_types.inc	(revision 311)
+++ trunk/nv/lib/detail/gl_ext/gl_ext_all_types.inc	(revision 311)
@@ -0,0 +1,2 @@
+#include <nv/lib/detail/gl_ext/gl_ext_framebuffer_object_types.inc>
+#include <nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_types.inc>
Index: trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_functions.inc
===================================================================
--- trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_functions.inc	(revision 311)
+++ trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_functions.inc	(revision 311)
@@ -0,0 +1,3 @@
+/* GL_EXT_FRAMEBUFFER_BLIT */
+NV_GL_FUN_EXT( void , glBlitFramebuffer , ( GLint , GLint , GLint , GLint , GLint , GLint , GLint , GLint , GLbitfield , GLenum ) );
+
Index: trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_types.inc
===================================================================
--- trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_types.inc	(revision 311)
+++ trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_types.inc	(revision 311)
@@ -0,0 +1,6 @@
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_FRAMEBUFFER_BINDING 0x8CA6 
+
Index: trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_object_functions.inc
===================================================================
--- trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_object_functions.inc	(revision 311)
+++ trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_object_functions.inc	(revision 311)
@@ -0,0 +1,18 @@
+/* GL_EXT_FRAMEBUFFER */
+NV_GL_FUN_EXT( void , glBindFramebuffer , ( GLenum , GLuint ) );
+NV_GL_FUN_EXT( void , glBindRenderbuffer , ( GLenum , GLuint ) );
+NV_GL_FUN_EXT( GLenum , glCheckFramebufferStatus , ( GLenum ) );
+NV_GL_FUN_EXT( void , glDeleteFramebuffers , ( GLsizei , const GLuint*) );
+NV_GL_FUN_EXT( void , glDeleteRenderbuffers , ( GLsizei , const GLuint*) );
+NV_GL_FUN_EXT( void , glFramebufferRenderbuffer , ( GLenum , GLenum , GLenum , GLuint ) );
+NV_GL_FUN_EXT( void , glFramebufferTexture1D , ( GLenum , GLenum , GLenum , GLuint , GLint ) );
+NV_GL_FUN_EXT( void , glFramebufferTexture2D , ( GLenum , GLenum , GLenum , GLuint , GLint ) );
+NV_GL_FUN_EXT( void , glFramebufferTexture3D , ( GLenum , GLenum , GLenum , GLuint , GLint , GLint ) );
+NV_GL_FUN_EXT( void , glGenFramebuffers , ( GLsizei , GLuint* ) );
+NV_GL_FUN_EXT( void , glGenRenderbuffers , ( GLsizei , GLuint* ) );
+NV_GL_FUN_EXT( void , glGenerateMipmap , ( GLenum ) );
+NV_GL_FUN_EXT( void , glGetFramebufferAttachmentParameteriv , ( GLenum , GLenum , GLenum , GLint* ) );
+NV_GL_FUN_EXT( void , glGetRenderbufferParameteriv , ( GLenum , GLenum , GLint* ) );
+NV_GL_FUN_EXT( GLboolean , glIsFramebuffer , ( GLuint ) );
+NV_GL_FUN_EXT( GLboolean , glIsRenderbuffer , ( GLuint ) );
+NV_GL_FUN_EXT( void , glRenderbufferStorage , ( GLenum , GLenum , GLsizei , GLsizei ) );
Index: trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_object_types.inc
===================================================================
--- trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_object_types.inc	(revision 311)
+++ trunk/nv/lib/detail/gl_ext/gl_ext_framebuffer_object_types.inc	(revision 311)
@@ -0,0 +1,51 @@
+ #define GL_FRAMEBUFFER     0x8D40
+ #define GL_RENDERBUFFER    0x8D41
+ #define GL_STENCIL_INDEX1  0x8D46
+ #define GL_STENCIL_INDEX4  0x8D47
+ #define GL_STENCIL_INDEX8  0x8D48
+ #define GL_STENCIL_INDEX16 0x8D49
+ #define GL_RENDERBUFFER_WIDTH      0x8D42
+ #define GL_RENDERBUFFER_HEIGHT     0x8D43
+ #define GL_RENDERBUFFER_INTERNAL_FORMAT    0x8D44
+ #define GL_RENDERBUFFER_RED_SIZE   0x8D50
+ #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+ #define GL_RENDERBUFFER_BLUE_SIZE  0x8D52
+ #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+ #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+ #define GL_RENDERBUFFER_STENCIL_SIZE       0x8D55
+ #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE    0x8CD0
+ #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME    0x8CD1
+ #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL  0x8CD2
+ #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE  0x8CD3
+ #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET     0x8CD4
+ #define GL_COLOR_ATTACHMENT0 0x8CE0
+ #define GL_COLOR_ATTACHMENT1 0x8CE1
+ #define GL_COLOR_ATTACHMENT2 0x8CE2
+ #define GL_COLOR_ATTACHMENT3 0x8CE3
+ #define GL_COLOR_ATTACHMENT4 0x8CE4
+ #define GL_COLOR_ATTACHMENT5 0x8CE5
+ #define GL_COLOR_ATTACHMENT6 0x8CE6
+ #define GL_COLOR_ATTACHMENT7 0x8CE7
+ #define GL_COLOR_ATTACHMENT8 0x8CE8
+ #define GL_COLOR_ATTACHMENT9 0x8CE9
+ #define GL_COLOR_ATTACHMENT10       0x8CEA
+ #define GL_COLOR_ATTACHMENT11       0x8CEB
+ #define GL_COLOR_ATTACHMENT12       0x8CEC
+ #define GL_COLOR_ATTACHMENT13       0x8CED
+ #define GL_COLOR_ATTACHMENT14       0x8CEE
+ #define GL_COLOR_ATTACHMENT15       0x8CEF
+ #define GL_DEPTH_ATTACHMENT 0x8D00
+ #define GL_STENCIL_ATTACHMENT       0x8D20
+ #define GL_FRAMEBUFFER_COMPLETE  0x8CD5
+ #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT     0x8CD6
+ #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT     0x8CD7
+ #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS     0x8CD9
+ #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS0x8CDA
+ #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER    0x8CDB
+ #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER    0x8CDC
+ #define GL_FRAMEBUFFER_UNSUPPORTED       0x8CDD
+ #define GL_FRAMEBUFFER_BINDING     0x8CA6
+ #define GL_RENDERBUFFER_BINDING    0x8CA7
+ #define GL_MAX_COLOR_ATTACHMENTS   0x8CDF
+ #define GL_MAX_RENDERBUFFER_SIZE   0x84E8
+ #define GL_INVALID_FRAMEBUFFER_OPERATION   0x0506
Index: trunk/nv/lib/detail/gl_ext/gl_ext_info.inc
===================================================================
--- trunk/nv/lib/detail/gl_ext/gl_ext_info.inc	(revision 311)
+++ trunk/nv/lib/detail/gl_ext/gl_ext_info.inc	(revision 311)
@@ -0,0 +1,2 @@
+NV_GL_EXTENSION( 1, FRAMEBUFFER_OBJECT, framebuffer_object )
+NV_GL_EXTENSION( 2, FRAMEBUFFER_BLIT, framebuffer_blit )
Index: trunk/nv/lib/detail/gl_functions.inc
===================================================================
--- trunk/nv/lib/detail/gl_functions.inc	(revision 310)
+++ trunk/nv/lib/detail/gl_functions.inc	(revision 311)
@@ -180,25 +180,2 @@
 NV_GL_FUN_EXT( void , glUniformMatrix4x3fv , ( GLint , GLsizei , GLboolean , const GLfloat *) );
 
-/* GL_EXT_FRAMEBUFFER */
-NV_GL_FUN_EXT( void , glBindFramebuffer , ( GLenum , GLuint ) );
-NV_GL_FUN_EXT( void , glBindRenderbuffer , ( GLenum , GLuint ) );
-NV_GL_FUN_EXT( GLenum , glCheckFramebufferStatus , ( GLenum ) );
-NV_GL_FUN_EXT( void , glDeleteFramebuffers , ( GLsizei , const GLuint*) );
-NV_GL_FUN_EXT( void , glDeleteRenderbuffers , ( GLsizei , const GLuint*) );
-NV_GL_FUN_EXT( void , glFramebufferRenderbuffer , ( GLenum , GLenum , GLenum , GLuint ) );
-NV_GL_FUN_EXT( void , glFramebufferTexture1D , ( GLenum , GLenum , GLenum , GLuint , GLint ) );
-NV_GL_FUN_EXT( void , glFramebufferTexture2D , ( GLenum , GLenum , GLenum , GLuint , GLint ) );
-NV_GL_FUN_EXT( void , glFramebufferTexture3D , ( GLenum , GLenum , GLenum , GLuint , GLint , GLint ) );
-NV_GL_FUN_EXT( void , glGenFramebuffers , ( GLsizei , GLuint* ) );
-NV_GL_FUN_EXT( void , glGenRenderbuffers , ( GLsizei , GLuint* ) );
-NV_GL_FUN_EXT( void , glGenerateMipmap , ( GLenum ) );
-NV_GL_FUN_EXT( void , glGetFramebufferAttachmentParameteriv , ( GLenum , GLenum , GLenum , GLint* ) );
-NV_GL_FUN_EXT( void , glGetRenderbufferParameteriv , ( GLenum , GLenum , GLint* ) );
-NV_GL_FUN_EXT( GLboolean , glIsFramebuffer , ( GLuint ) );
-NV_GL_FUN_EXT( GLboolean , glIsRenderbuffer , ( GLuint ) );
-NV_GL_FUN_EXT( void , glRenderbufferStorage , ( GLenum , GLenum , GLsizei , GLsizei ) );
-// NV_GL_FUN_EXT( void , glBlitFramebuffer , ( GLint , GLint , GLint , GLint , GLint , GLint , GLint , GLint , GLbitfield , GLenum ) );
-// NV_GL_FUN_EXT( void , glFramebufferTextureLayer , ( GLenum , GLenum , GLuint , GLint , GLint ) );
-// NV_GL_FUN_EXT( void , glRenderbufferStorageMultisample , ( GLenum , GLsizei , GLenum , GLsizei , GLsizei ) );
-
-
Index: trunk/nv/lib/gl.hh
===================================================================
--- trunk/nv/lib/gl.hh	(revision 310)
+++ trunk/nv/lib/gl.hh	(revision 311)
@@ -54,4 +54,5 @@
 #include <nv/lib/detail/wgl_types.inc>
 #endif
+#include <nv/lib/detail/gl_ext/gl_ext_all_types.inc>
 
 #if defined(NV_GL_DYNAMIC)
@@ -67,4 +68,5 @@
 #include <nv/lib/detail/wgl_functions.inc>
 #endif
+#include <nv/lib/detail/gl_ext/gl_ext_all_functions.inc>
 
 #undef NV_GL_FUN_REN
@@ -75,12 +77,29 @@
 
 namespace nv {
-/* Dynamic load support */
+
+	enum gl_extensions
+	{
+		EXT_NONE                = 0,
+#define NV_GL_EXTENSION( count, id, name ) GL_EXT_##id = 1u << (count-1),
+#include <nv/lib/detail/gl_ext/gl_ext_info.inc>
+#undef NV_GL_EXTENSION
+//		EXT_PIXEL_BUFFER_OBJECT = 0x00000004,
+//		EXT_TEXTURE_CUBE_MAP    = 0x00000008,
+//		EXT_TEXTURE_3D	        = 0x00000010,
+	};
+
+	const char* get_gl_extension_name( gl_extensions extension );
+	bool load_gl_extension( gl_extensions extension );
+	gl_extensions load_gl_extensions( uint32 extensions );
+	bool is_gl_extension_loaded( gl_extensions extensions );
+	bool are_gl_extensions_loaded( uint32 extensions );
 	bool load_gl_no_context( const char* path = NV_GL_PATH );
+	/* Dynamic load support */
 #	if defined( NV_GL_DYNAMIC )
-		bool load_gl_library( const char* path = NV_GL_PATH );
-		bool load_wgl_library( const char* path = NV_GL_PATH );
+		bool load_gl_library( const char* path = NV_GL_PATH, bool force_reload = false );
+		bool load_wgl_library( const char* path = NV_GL_PATH, bool force_reload = false );
 #	else
-		inline bool load_gl_library( const char* path = "" ) { return true; }
-		inline bool load_wgl_library( const char* path = "" ) { return true; }
+		inline bool load_gl_library( const char* = "", bool = false ) { return true; }
+		inline bool load_wgl_library( const char* = "", bool = false ) { return true; }
 #	endif
 }
Index: trunk/nv/logging.hh
===================================================================
--- trunk/nv/logging.hh	(revision 310)
+++ trunk/nv/logging.hh	(revision 311)
@@ -56,5 +56,5 @@
 #define NV_LOG(level, message_stream) \
 	if ( nv::logger_base::is_valid() && \
-		(unsigned int)nv::logger_base::reference().get_level() >= level ) \
+		(unsigned int)nv::logger_base::reference().get_level() >= (unsigned int)level ) \
 	{       \
 		std::stringstream ss; \
@@ -66,5 +66,5 @@
 #define NV_DEBUG_LOG(level, message_stream) \
 	if ( nv::logger_base::is_valid() && \
-		(unsigned int)nv::logger_base::reference().get_level() >= level ) \
+		(unsigned int)nv::logger_base::reference().get_level() >= (unsigned int)level ) \
 	{       \
 		std::stringstream ss; \
Index: trunk/src/gl/gl_context.cc
===================================================================
--- trunk/src/gl/gl_context.cc	(revision 310)
+++ trunk/src/gl/gl_context.cc	(revision 311)
@@ -612,4 +612,6 @@
 	}     
 
+	load_gl_library( NV_GL_PATH, true );
+	load_wgl_library( NV_GL_PATH, true );
 	m_handle = (void*)handle;
 #else
Index: trunk/src/lib/gl.cc
===================================================================
--- trunk/src/lib/gl.cc	(revision 310)
+++ trunk/src/lib/gl.cc	(revision 311)
@@ -6,4 +6,5 @@
 
 #include "nv/common.hh"
+#include "nv/range.hh"
 #include "nv/lib/gl.hh"
 
@@ -33,4 +34,5 @@
 #include <nv/lib/detail/wgl_functions.inc>
 #endif
+#include <nv/lib/detail/gl_ext/gl_ext_all_functions.inc>
 #undef NV_GL_FUN_REN
 #undef NV_GL_FUN_EXT
@@ -38,25 +40,64 @@
 
 static nv::library gl_library;
+static nv::gl_extensions gl_loaded_extensions = nv::gl_extensions(0);
+extern "C" void* (NV_GL_APIENTRY *gl_ext_loader) ( const char* ) = nullptr;
 static bool gl_library_loaded = false;
 static bool wgl_library_loaded = false;
 
-bool nv::load_gl_library( const char* path )
-{
-	if ( gl_library_loaded ) return true;
+static const char *gl_extension_names[] = {
+	"UNKNOWN",
+#define NV_GL_EXTENSION( count, id, name ) "GL_EXT_"#id,
+#include <nv/lib/detail/gl_ext/gl_ext_info.inc>
+#undef NV_GL_EXTENSION
+};
+
+static const char *gl_extension_ids[] = {
+	"UNKNOWN",
+#define NV_GL_EXTENSION( count, id, name ) #id,
+#include <nv/lib/detail/gl_ext/gl_ext_info.inc>
+#undef NV_GL_EXTENSION
+};
+
+
+static void* load_gl_ext_symbol_impl( const char* name, nv::log_level fail_level = nv::LOG_DEBUG )
+{
+	void* result = gl_ext_loader( name );
+	NV_LOG( ( result ? nv::LOG_DEBUG : fail_level ), "load_gl_ext_symbol : " << name << ( result ? " succeded." : "failed." ) );
+	return result;
+}
+
+static void* load_gl_ext_symbol( const char* name, bool iterate, const char* ext )
+{
+	void * result        = nullptr;
+	result = load_gl_ext_symbol_impl( ext ? ( std::string(name) + ext ).c_str() : name );
+	if ( result ) return result;
+	if ( iterate )
+	{
+		result = gl_ext_loader( (std::string(name) + "ARB").c_str() );
+		if ( result ) return result;
+		result = gl_ext_loader( (std::string(name) + "EXT").c_str() );
+		if ( result ) return result;
+	}
+	return result;
+}
+
+bool nv::load_gl_library( const char* path, bool force_reload )
+{
+	if ( gl_library_loaded && !force_reload ) return true;
 #if defined( NV_SDL_GL )
 #		define NV_GL_LOAD( symbol ) *(void **) (&symbol) = SDL_GL_GetProcAddress(#symbol);
 #		define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = SDL_GL_GetProcAddress(#symbol);
+	*(void **) (&gl_ext_loader) = SDL_GL_GetProcAddress;
 #else
 	if ( !gl_library.is_open() ) gl_library.open( path );
 
-	void * (NV_GL_APIENTRY *ext_loader) (const char* proc) = nullptr;
 #	if NV_PLATFORM == NV_WINDOWS 
 #		define NV_GL_LOAD( symbol ) *(void **) (&symbol) = gl_library.get(#symbol);
-		*(void **) (&ext_loader) = gl_library.get("wglGetProcAddress");
-#		define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = ext_loader(#symbol);
+		*(void **) (&gl_ext_loader) = gl_library.get("wglGetProcAddress");
+#		define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = gl_ext_loader(#symbol);
 #	elif (NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE)
 #		define NV_GL_LOAD( symbol ) *(void **) (&symbol) = gl_library.get(#symbol);
-		*(void **) (&ext_loader) = gl_library.get("glXGetProcAddress");
-#		define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = ext_loader(#symbol);
+		*(void **) (&gl_ext_loader) = gl_library.get("glXGetProcAddress");
+#		define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = gl_ext_loader(#symbol);
 #	else
 #		define NV_GL_LOAD( symbol ) *(void **) (&symbol) = gl_library.get(#symbol);
@@ -77,7 +118,7 @@
 }
 
-bool nv::load_wgl_library( const char* path /*= NV_GL_PATH */ )
-{
-	if ( wgl_library_loaded ) return true;
+bool nv::load_wgl_library( const char* path /*= NV_GL_PATH */, bool force_reload )
+{
+	if ( wgl_library_loaded && !force_reload ) return true;
 #if NV_PLATFORM == NV_WINDOWS 
 #if defined( NV_SDL_GL )
@@ -85,11 +126,11 @@
 #		define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = SDL_GL_GetProcAddress(#symbol);
 #	    define NV_GL_LOAD_REN( fname, rname )  *(void **) (&rname) = SDL_GL_GetProcAddress(#fname);
+	(void **) (&gl_ext_loader) = SDL_GL_GetProcAddress;
 #else // 
 	if ( !gl_library.is_open() ) gl_library.open( path );
 
-	void * (NV_GL_APIENTRY *ext_loader) (const char* proc) = nullptr;
-	*(void **) (&ext_loader) = gl_library.get("wglGetProcAddress");
+	*(void **) (&gl_ext_loader) = gl_library.get("wglGetProcAddress");
 #define NV_GL_LOAD( symbol ) *(void **) (&symbol) = gl_library.get(#symbol);
-#define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = ext_loader(#symbol);
+#define NV_GL_LOAD_EXT( symbol ) *(void **) (&symbol) = gl_ext_loader(#symbol);
 #define NV_GL_LOAD_REN( fname, rname ) *(void **) (&rname) = gl_library.get(#fname);
 #endif 
@@ -186,2 +227,84 @@
 }
 
+const char* nv::get_gl_extension_name( gl_extensions extension )
+{
+	uint32 value = uint32( extension );
+	uint32 index = 0; 
+	while ( value >>= 1 ) index++;
+	return NV_SAFE_ARRAY(gl_extension_names, index+1, gl_extension_names[0] );
+}
+
+
+bool nv::load_gl_extension( gl_extensions extension )
+{
+	const char* name = get_gl_extension_name( extension );
+	// TODO: first check for support using gl mechanisms 
+	//       see SDL 2.0 SDL_video.c
+	if ( !gl_library.is_open() ) 
+	{
+		NV_LOG( nv::LOG_ERROR, "load_gl_extension used, while gl_library was closed!" );
+		return false;
+	}
+
+	if ( gl_ext_loader == nullptr )
+	{
+		NV_LOG( nv::LOG_ERROR, "load_gl_extension used, while gl_ext_loader was undefined!" );
+		return false;
+	}
+	NV_LOG( nv::LOG_DEBUG, "load_gl_extension - loading extension - \"" << name << "\"..." );
+
+	uint32 count      = 0; 
+	uint32 fail_count = 0;
+
+#	define NV_GL_FUN_EXT( rtype, symbol, fparams ) \
+	*(void **) (&symbol) = load_gl_ext_symbol(#symbol, true, nullptr); \
+	count++; if ( !symbol ) fail_count++;
+
+	switch ( extension )
+	{
+	case GL_EXT_FRAMEBUFFER_BLIT : {
+#include <nv/lib/detail/gl_ext/gl_ext_framebuffer_blit_functions.inc>
+	} break;
+	case GL_EXT_FRAMEBUFFER_OBJECT : {
+#include <nv/lib/detail/gl_ext/gl_ext_framebuffer_object_functions.inc>
+	} break;
+	default : {
+		NV_LOG( nv::LOG_ERROR, "load_gl_extension - unknown extension \"" << name << "\"!" );
+		return nullptr;
+	}
+	}
+#	undef NV_GL_FUN_EXT
+
+	if ( fail_count == 0 )
+	{
+		NV_LOG( nv::LOG_NOTICE, "load_gl_extension - extension \"" << name << "\" loaded (" << count << " symbols)" );
+		return false;
+	}
+	NV_LOG( nv::LOG_NOTICE, "load_gl_extension - failed to load extension \"" << name << "\" (" << count << "/" << fail_count << " symbols loaded)" );
+	return true;
+}
+
+nv::gl_extensions nv::load_gl_extensions( uint32 extensions )
+{
+	gl_extensions result = gl_extensions(0);
+	for ( auto ext : nv::bits( gl_extensions(extensions) ) )
+	{
+		if ( load_gl_extension(ext) ) result = gl_extensions( result | ext );
+	}
+	return result;
+}
+
+bool nv::is_gl_extension_loaded( gl_extensions extensions )
+{
+	return ( gl_loaded_extensions & extensions ) != 0;
+}
+
+bool nv::are_gl_extensions_loaded( uint32 extensions )
+{
+	for ( auto ext : nv::bits( gl_extensions(extensions) ) )
+	{
+		if ( !is_gl_extension_loaded(ext) ) return false;
+	}
+	return true;
+}
+
