#include "stdafx.h"

namespace glext
{

// WindoZe расширения
PFNWGLGETEXTENSIONSSTRINGEXTPROC                wglGetExtensionsStringEXT                = NULL;
PFNWGLGETEXTENSIONSSTRINGARBPROC				wglGetExtensionsStringARB                = NULL;

// WGL_ARB_pixel_format
PFNWGLGETPIXELFORMATATTRIBIVARBPROC				wglGetPixelFormatAttribivARB             = NULL;
PFNWGLGETPIXELFORMATATTRIBFVARBPROC				wglGetPixelFormatAttribfvARB             = NULL;
PFNWGLCHOOSEPIXELFORMATARBPROC					wglChoosePixelFormatARB                  = NULL;

// VSync																		
PFNWGLSWAPINTERVALEXTPROC                       wglSwapIntervalEXT                       = NULL;
PFNWGLGETSWAPINTERVALEXTPROC                    wglGetSwapIntervalEXT                    = NULL;

// ARB точки и спрайты
PFNGLPOINTPARAMETERFARBPROC                     glPointParameterfARB                     = NULL;
PFNGLPOINTPARAMETERFVARBPROC                    glPointParameterfvARB                    = NULL;
																				
// Мультимординг																
PFNGLACTIVETEXTUREARBPROC                       glActiveTextureARB                       = NULL;
PFNGLCLIENTACTIVETEXTUREARBPROC                 glClientActiveTextureARB                 = NULL;
PFNGLMULTITEXCOORD1FARBPROC                     glMultiTexCoord1f                        = NULL;
PFNGLMULTITEXCOORD1FVARBPROC                    glMultiTexCoord1fv                       = NULL;
PFNGLMULTITEXCOORD2FARBPROC                     glMultiTexCoord2f                        = NULL;
PFNGLMULTITEXCOORD2FVARBPROC                    glMultiTexCoord2fv                       = NULL;
PFNGLMULTITEXCOORD3FARBPROC                     glMultiTexCoord3f                        = NULL;
PFNGLMULTITEXCOORD3FVARBPROC                    glMultiTexCoord3fv                       = NULL;
PFNGLMULTITEXCOORD4FARBPROC                     glMultiTexCoord4f                        = NULL;
PFNGLMULTITEXCOORD4FVARBPROC                    glMultiTexCoord4fv                       = NULL;
																				
// Трехмерные текстуры															
PFNGLTEXIMAGE3DEXTPROC                          glTexImage3DEXT                          = NULL;
PFNGLTEXSUBIMAGE3DEXTPROC                       glTexSubImage3DEXT                       = NULL;
PFNGLCOPYTEXSUBIMAGE3DEXTPROC                   glCopyTexSubImage3DEXT                   = NULL;
																				
// Сжатые текстуры																
PFNGLCOMPRESSEDTEXIMAGE1DARBPROC                glCompressedTexImage1DARB                = NULL;
PFNGLCOMPRESSEDTEXIMAGE2DARBPROC                glCompressedTexImage2DARB                = NULL;
PFNGLCOMPRESSEDTEXIMAGE3DARBPROC                glCompressedTexImage3DARB                = NULL;
PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC             glCompressedTexSubImage1DARB             = NULL;
PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC             glCompressedTexSubImage2DARB             = NULL;
PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC             glCompressedTexSubImage3DARB             = NULL;
PFNGLGETCOMPRESSEDTEXIMAGEARBPROC               glGetCompressedTexImageARB               = NULL;
																				
// glDrawRangeElementsEXT														
PFNGLDRAWRANGEELEMENTSPROC                      glDrawRangeElementsEXT                   = NULL;

// Вертексные буфферы
PFNGLBINDBUFFERARBPROC                          glBindBufferARB                          = NULL;
PFNGLDELETEBUFFERSARBPROC                       glDeleteBuffersARB                       = NULL;
PFNGLGENBUFFERSARBPROC                          glGenBuffersARB                          = NULL;
PFNGLISBUFFERARBPROC                            glIsBufferARB                            = NULL;
PFNGLBUFFERDATAARBPROC                          glBufferDataARB                          = NULL;
PFNGLBUFFERSUBDATAARBPROC                       glBufferSubDataARB                       = NULL;
PFNGLGETBUFFERSUBDATAARBPROC                    glGetBufferSubDataARB                    = NULL;
PFNGLMAPBUFFERARBPROC                           glMapBufferARB                           = NULL;
PFNGLUNMAPBUFFERARBPROC                         glUnmapBufferARB                         = NULL;
PFNGLGETBUFFERPARAMETERIVARBPROC                glGetBufferParameterivARB                = NULL;
PFNGLGETBUFFERPOINTERVARBPROC                   glGetBufferPointervARB                   = NULL;
// vao
PFNGLBINDVERTEXARRAYPROC                        glBindVertexArray                        = NULL;
PFNGLDELETEVERTEXARRAYSPROC                     glDeleteVertexArrays                     = NULL;
PFNGLGENVERTEXARRAYSPROC                        glGenVertexArrays                        = NULL;
PFNGLISVERTEXARRAYPROC                          glIsVertexArray                          = NULL;

// Для ASM-шейдеров
PFNGLGENPROGRAMSARBPROC                         glGenProgramsARB                         = NULL;
PFNGLDELETEPROGRAMSARBPROC                      glDeleteProgramsARB                      = NULL;
PFNGLBINDPROGRAMARBPROC                         glBindProgramARB                         = NULL;
PFNGLISPROGRAMARBPROC                           glIsProgramARB                           = NULL;															   
PFNGLPROGRAMSTRINGARBPROC                       glProgramStringARB                       = NULL;
PFNGLGETPROGRAMIVARBPROC                        glGetProgramivARB                        = NULL;															   
PFNGLVERTEXATTRIB4FARBPROC                      glVertexAttrib4fARB                      = NULL;
PFNGLVERTEXATTRIB4FVARBPROC                     glVertexAttrib4fvARB                     = NULL;
PFNGLVERTEXATTRIB3FARBPROC                      glVertexAttrib3fARB                      = NULL;
PFNGLVERTEXATTRIB3FVARBPROC                     glVertexAttrib3fvARB                     = NULL;
PFNGLVERTEXATTRIBPOINTERARBPROC                 glVertexAttribPointerARB                 = NULL;
PFNGLENABLEVERTEXATTRIBARRAYARBPROC             glEnableVertexAttribArrayARB             = NULL;
PFNGLDISABLEVERTEXATTRIBARRAYARBPROC            glDisableVertexAttribArrayARB            = NULL;
PFNGLPROGRAMLOCALPARAMETER4FARBPROC             glProgramLocalParameter4fARB             = NULL;
PFNGLPROGRAMLOCALPARAMETER4FVARBPROC            glProgramLocalParameter4fvARB            = NULL;
PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC          glGetProgramLocalParameterfvARB          = NULL;
PFNGLPROGRAMENVPARAMETER4FARBPROC               glProgramEnvParameter4fARB               = NULL;
PFNGLPROGRAMENVPARAMETER4FVARBPROC              glProgramEnvParameter4fvARB              = NULL;
PFNGLGETPROGRAMENVPARAMETERFVARBPROC            glGetProgramEnvParameterfvARB            = NULL;

// Для PBuffer'ов
PFNWGLCREATEPBUFFERARBPROC                      wglCreatePbufferARB                      = NULL;
PFNWGLGETPBUFFERDCARBPROC                       wglGetPbufferDCARB                       = NULL;
PFNWGLRELEASEPBUFFERDCARBPROC                   wglReleasePbufferDCARB                   = NULL;
PFNWGLDESTROYPBUFFERARBPROC                     wglDestroyPbufferARB                     = NULL;
PFNWGLQUERYPBUFFERARBPROC                       wglQueryPbufferARB                       = NULL;
//PFNWGLCHOOSEPIXELFORMATARBPROC                  wglChoosePixelFormatARB                  = NULL;
PFNWGLBINDTEXIMAGEARBPROC                       wglBindTexImageARB                       = NULL;
PFNWGLRELEASETEXIMAGEARBPROC                    wglReleaseTexImageARB                    = NULL;
PFNWGLSETPBUFFERATTRIBARBPROC                   wglSetPbufferAttribARB                   = NULL;

// Для GLSL-шейдеров
PFNGLDELETEOBJECTARBPROC                        glDeleteObjectARB                        = NULL;
PFNGLGETHANDLEARBPROC                           glGetHandleARB                           = NULL;
PFNGLDETACHOBJECTARBPROC                        glDetachObjectARB                        = NULL;
PFNGLCREATESHADEROBJECTARBPROC                  glCreateShaderObjectARB                  = NULL;
PFNGLSHADERSOURCEARBPROC                        glShaderSourceARB                        = NULL;
PFNGLCOMPILESHADERARBPROC                       glCompileShaderARB                       = NULL;
PFNGLCREATEPROGRAMOBJECTARBPROC                 glCreateProgramObjectARB                 = NULL;
PFNGLATTACHOBJECTARBPROC                        glAttachObjectARB                        = NULL;
PFNGLLINKPROGRAMARBPROC                         glLinkProgramARB                         = NULL;
PFNGLUSEPROGRAMOBJECTARBPROC                    glUseProgramObjectARB                    = NULL;
PFNGLVALIDATEPROGRAMARBPROC                     glValidateProgramARB                     = NULL;
PFNGLUNIFORM1FARBPROC                           glUniform1fARB                           = NULL;
PFNGLUNIFORM2FARBPROC                           glUniform2fARB                           = NULL;
PFNGLUNIFORM3FARBPROC                           glUniform3fARB                           = NULL;
PFNGLUNIFORM4FARBPROC                           glUniform4fARB                           = NULL;
PFNGLUNIFORM1IARBPROC                           glUniform1iARB                           = NULL;
PFNGLUNIFORM2IARBPROC                           glUniform2iARB                           = NULL;
PFNGLUNIFORM3IARBPROC                           glUniform3iARB                           = NULL;
PFNGLUNIFORM4IARBPROC                           glUniform4iARB                           = NULL;
PFNGLUNIFORM1FVARBPROC                          glUniform1fvARB                          = NULL;
PFNGLUNIFORM2FVARBPROC                          glUniform2fvARB                          = NULL;
PFNGLUNIFORM3FVARBPROC                          glUniform3fvARB                          = NULL;
PFNGLUNIFORM4FVARBPROC                          glUniform4fvARB                          = NULL;
PFNGLUNIFORM1IVARBPROC                          glUniform1ivARB                          = NULL;
PFNGLUNIFORM2IVARBPROC                          glUniform2ivARB                          = NULL;
PFNGLUNIFORM3IVARBPROC                          glUniform3ivARB                          = NULL;
PFNGLUNIFORM4IVARBPROC                          glUniform4ivARB                          = NULL;
PFNGLUNIFORMMATRIX2FVARBPROC                    glUniformMatrix2fvARB                    = NULL;
PFNGLUNIFORMMATRIX3FVARBPROC                    glUniformMatrix3fvARB                    = NULL;
PFNGLUNIFORMMATRIX4FVARBPROC                    glUniformMatrix4fvARB                    = NULL;
PFNGLGETOBJECTPARAMETERFVARBPROC                glGetObjectParameterfvARB                = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC                glGetObjectParameterivARB                = NULL;
PFNGLGETINFOLOGARBPROC                          glGetInfoLogARB                          = NULL;
PFNGLGETATTACHEDOBJECTSARBPROC                  glGetAttachedObjectsARB                  = NULL;
PFNGLGETUNIFORMLOCATIONARBPROC                  glGetUniformLocationARB                  = NULL;
PFNGLGETACTIVEUNIFORMARBPROC                    glGetActiveUniformARB                    = NULL;
PFNGLGETUNIFORMFVARBPROC                        glGetUniformfvARB                        = NULL;
PFNGLGETUNIFORMIVARBPROC                        glGetUniformivARB                        = NULL;
PFNGLGETSHADERSOURCEARBPROC                     glGetShaderSourceARB                     = NULL;
PFNGLBINDATTRIBLOCATIONARBPROC                  glBindAttribLocationARB                  = NULL;
PFNGLGETACTIVEATTRIBARBPROC                     glGetActiveAttribARB                     = NULL;
PFNGLGETATTRIBLOCATIONARBPROC                   glGetAttribLocationARB                   = NULL;
PFNGLGETVERTEXATTRIBFVARBPROC                   glGetVertexAttribfvARB                   = NULL;

// для RTT ( FBO )
PFNGLISRENDERBUFFEREXTPROC                      glIsRenderbufferEXT                      = NULL;
PFNGLBINDRENDERBUFFEREXTPROC                    glBindRenderbufferEXT                    = NULL;
PFNGLDELETERENDERBUFFERSEXTPROC                 glDeleteRenderbuffersEXT                 = NULL;
PFNGLGENRENDERBUFFERSEXTPROC                    glGenRenderbuffersEXT                    = NULL;
PFNGLRENDERBUFFERSTORAGEEXTPROC                 glRenderbufferStorageEXT                 = NULL;
PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC          glGetRenderbufferParameterivEXT          = NULL;
PFNGLISFRAMEBUFFEREXTPROC                       glIsFramebufferEXT                       = NULL;
PFNGLBINDFRAMEBUFFEREXTPROC                     glBindFramebufferEXT                     = NULL;
PFNGLDELETEFRAMEBUFFERSEXTPROC                  glDeleteFramebuffersEXT                  = NULL;
PFNGLGENFRAMEBUFFERSEXTPROC                     glGenFramebuffersEXT                     = NULL;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC              glCheckFramebufferStatusEXT              = NULL;
PFNGLFRAMEBUFFERTEXTURE1DEXTPROC                glFramebufferTexture1DEXT                = NULL;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC                glFramebufferTexture2DEXT                = NULL;
PFNGLFRAMEBUFFERTEXTURE3DEXTPROC                glFramebufferTexture3DEXT                = NULL;
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC             glFramebufferRenderbufferEXT             = NULL;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
PFNGLGENERATEMIPMAPEXTPROC                      glGenerateMipmapEXT                      = NULL;

// для раздельных blend-factors по RGB и ALPHA
PFNGLBLENDFUNCSEPARATEPROC						glBlendFuncSeparateEXT                   = NULL;
PFNGLBLENDEQUATIONSEPARATEEXTPROC				glBlendEquationSeparateEXT               = NULL;
PFNGLBLENDEQUATIONEXTPROC						glBlendEquationEXT                       = NULL;



// инициализация WGL_ARB_pixel_format
bool InitARB_pixel_format( void )
{
	wglGetPixelFormatAttribivARB = ( PFNWGLGETPIXELFORMATATTRIBIVARBPROC ) OpenGL_3::ProcedureAddress( "wglGetPixelFormatAttribivARB" );
	wglGetPixelFormatAttribfvARB = ( PFNWGLGETPIXELFORMATATTRIBFVARBPROC ) OpenGL_3::ProcedureAddress( "wglGetPixelFormatAttribfvARB" );
	wglChoosePixelFormatARB      = ( PFNWGLCHOOSEPIXELFORMATARBPROC      ) OpenGL_3::ProcedureAddress( "wglChoosePixelFormatARB"      );

	return ( NULL != wglGetPixelFormatAttribivARB && NULL != wglGetPixelFormatAttribfvARB && NULL != wglChoosePixelFormatARB );
}

// инициализация расширений для мультимординга
bool InitMultitextureExtensions( void )
{
	glActiveTextureARB       = ( PFNGLACTIVETEXTUREARBPROC       ) OpenGL_3::ProcedureAddress( "glActiveTextureARB"       );
	glClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) OpenGL_3::ProcedureAddress( "glClientActiveTextureARB" );
	glMultiTexCoord1f        = ( PFNGLMULTITEXCOORD1FARBPROC     ) OpenGL_3::ProcedureAddress( "glMultiTexCoord1f"        );
	glMultiTexCoord1fv       = ( PFNGLMULTITEXCOORD1FVARBPROC    ) OpenGL_3::ProcedureAddress( "glMultiTexCoord1fv"       );
	glMultiTexCoord2f        = ( PFNGLMULTITEXCOORD2FARBPROC     ) OpenGL_3::ProcedureAddress( "glMultiTexCoord2f"        );
	glMultiTexCoord2fv       = ( PFNGLMULTITEXCOORD2FVARBPROC    ) OpenGL_3::ProcedureAddress( "glMultiTexCoord2fv"       );
	glMultiTexCoord3f        = ( PFNGLMULTITEXCOORD3FARBPROC     ) OpenGL_3::ProcedureAddress( "glMultiTexCoord3f"        );
	glMultiTexCoord3fv       = ( PFNGLMULTITEXCOORD3FVARBPROC    ) OpenGL_3::ProcedureAddress( "glMultiTexCoord3fv"       );
	glMultiTexCoord4f        = ( PFNGLMULTITEXCOORD4FARBPROC     ) OpenGL_3::ProcedureAddress( "glMultiTexCoord4f"        );
	glMultiTexCoord4fv       = ( PFNGLMULTITEXCOORD4FVARBPROC    ) OpenGL_3::ProcedureAddress( "glMultiTexCoord4fv"       );

	return ( glActiveTextureARB != NULL && glClientActiveTextureARB != NULL && glMultiTexCoord1f != NULL &&
			 glMultiTexCoord1fv != NULL && glMultiTexCoord2f != NULL && glMultiTexCoord2fv != NULL &&
			 glMultiTexCoord3f != NULL && glMultiTexCoord3fv != NULL && glMultiTexCoord4f != NULL &&
			 glMultiTexCoord4fv != NULL );
}

// Инициализация 3D текстур
bool Init3DTextures( void )
{
	glTexImage3DEXT        = ( PFNGLTEXIMAGE3DEXTPROC        ) OpenGL_3::ProcedureAddress( "glTexImage3DEXT"        );
	glTexSubImage3DEXT     = ( PFNGLTEXSUBIMAGE3DEXTPROC     ) OpenGL_3::ProcedureAddress( "glTexSubImage3DEXT"     );
	glCopyTexSubImage3DEXT = ( PFNGLCOPYTEXSUBIMAGE3DEXTPROC ) OpenGL_3::ProcedureAddress( "glCopyTexSubImage3DEXT" );

	return ( NULL != glTexImage3DEXT && NULL != glTexSubImage3DEXT && NULL != glCopyTexSubImage3DEXT );
}

// инициализация сжатых текстуры
bool InitCompressedTextures( void )
{
	glCompressedTexImage1DARB    = ( PFNGLCOMPRESSEDTEXIMAGE1DARBPROC    ) OpenGL_3::ProcedureAddress( "glCompressedTexImage1DARB"    );
	glCompressedTexImage2DARB    = ( PFNGLCOMPRESSEDTEXIMAGE2DARBPROC    ) OpenGL_3::ProcedureAddress( "glCompressedTexImage2DARB"    );
	glCompressedTexImage3DARB    = ( PFNGLCOMPRESSEDTEXIMAGE3DARBPROC    ) OpenGL_3::ProcedureAddress( "glCompressedTexImage3DARB"    );
	glCompressedTexSubImage1DARB = ( PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC ) OpenGL_3::ProcedureAddress( "glCompressedTexSubImage1DARB" );
	glCompressedTexSubImage2DARB = ( PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC ) OpenGL_3::ProcedureAddress( "glCompressedTexSubImage2DARB" );
	glCompressedTexSubImage3DARB = ( PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC ) OpenGL_3::ProcedureAddress( "glCompressedTexSubImage3DARB" );
	glGetCompressedTexImageARB   = ( PFNGLGETCOMPRESSEDTEXIMAGEARBPROC   ) OpenGL_3::ProcedureAddress( "glGetCompressedTexImageARB"   );

	return ( NULL != glCompressedTexImage1DARB && NULL != glCompressedTexImage2DARB &&
		     NULL != glCompressedTexImage3DARB && NULL != glCompressedTexSubImage1DARB &&
			 NULL != glCompressedTexSubImage2DARB && NULL != glCompressedTexSubImage3DARB && NULL != glGetCompressedTexImageARB );
}

// glDrawRangeElements
bool Init_glDrawRangeElements( void )
{
	glDrawRangeElementsEXT = ( PFNGLDRAWRANGEELEMENTSPROC ) OpenGL_3::ProcedureAddress( "glDrawRangeElementsEXT" );

	return ( NULL != glDrawRangeElementsEXT );
}

// инициализация вертексных буфферов
bool InitVBO( void )
{
	glBindBufferARB           = (PFNGLBINDBUFFERARBPROC          )OpenGL_3::ProcedureAddress("glBindBufferARB"          );
	glDeleteBuffersARB        = (PFNGLDELETEBUFFERSARBPROC       )OpenGL_3::ProcedureAddress("glDeleteBuffersARB"       );
	glGenBuffersARB           = (PFNGLGENBUFFERSARBPROC          )OpenGL_3::ProcedureAddress("glGenBuffersARB"          );
	glIsBufferARB             = (PFNGLISBUFFERARBPROC            )OpenGL_3::ProcedureAddress("glIsBufferARB"            );
	glBufferDataARB           = (PFNGLBUFFERDATAARBPROC          )OpenGL_3::ProcedureAddress("glBufferDataARB"          );
	glBufferSubDataARB        = (PFNGLBUFFERSUBDATAARBPROC       )OpenGL_3::ProcedureAddress("glBufferSubDataARB"       );
	glGetBufferSubDataARB     = (PFNGLGETBUFFERSUBDATAARBPROC    )OpenGL_3::ProcedureAddress("glGetBufferSubDataARB"    );
	glMapBufferARB            = (PFNGLMAPBUFFERARBPROC           )OpenGL_3::ProcedureAddress("glMapBufferARB"           );
	glUnmapBufferARB          = (PFNGLUNMAPBUFFERARBPROC         )OpenGL_3::ProcedureAddress("glUnmapBufferARB"         );
	glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)OpenGL_3::ProcedureAddress("glGetBufferParameterivARB");
	glGetBufferPointervARB    = (PFNGLGETBUFFERPOINTERVARBPROC   )OpenGL_3::ProcedureAddress("glGetBufferPointervARB"   );

	glBindVertexArray         = (PFNGLBINDVERTEXARRAYPROC   )OpenGL_3::ProcedureAddress("glBindVertexArray"   );
	glDeleteVertexArrays      = (PFNGLDELETEVERTEXARRAYSPROC)OpenGL_3::ProcedureAddress("glDeleteVertexArrays");
	glGenVertexArrays         = (PFNGLGENVERTEXARRAYSPROC   )OpenGL_3::ProcedureAddress("glGenVertexArrays"   );
	glIsVertexArray           = (PFNGLISVERTEXARRAYPROC     )OpenGL_3::ProcedureAddress("glIsVertexArray"     );

	return (glBindBufferARB != NULL && glDeleteBuffersARB != NULL && glGenBuffersARB != NULL &&
			glIsBufferARB != NULL && glBufferDataARB != NULL && glBufferSubDataARB != NULL &&
			glGetBufferSubDataARB != NULL && glMapBufferARB != NULL && glUnmapBufferARB != NULL &&
			glGetBufferParameterivARB != NULL && glGetBufferPointervARB != NULL &&
			glBindVertexArray != NULL && glDeleteVertexArrays != NULL && glGenVertexArrays != NULL && glIsVertexArray != NULL);
}

// инициализации расширений для GLSL
bool InitGLSLNeededExts( void )
{
	glDeleteObjectARB         = ( PFNGLDELETEOBJECTARBPROC         ) OpenGL_3::ProcedureAddress( "glDeleteObjectARB"         );
	glGetHandleARB            = ( PFNGLGETHANDLEARBPROC            ) OpenGL_3::ProcedureAddress( "glGetHandleARB"            );
	glDetachObjectARB         = ( PFNGLDETACHOBJECTARBPROC         ) OpenGL_3::ProcedureAddress( "glDetachObjectARB"         );
	glCreateShaderObjectARB   = ( PFNGLCREATESHADEROBJECTARBPROC   ) OpenGL_3::ProcedureAddress( "glCreateShaderObjectARB"   );
	glShaderSourceARB         = ( PFNGLSHADERSOURCEARBPROC         ) OpenGL_3::ProcedureAddress( "glShaderSourceARB"         );
	glCompileShaderARB        = ( PFNGLCOMPILESHADERARBPROC        ) OpenGL_3::ProcedureAddress( "glCompileShaderARB"        );
	glCreateProgramObjectARB  = ( PFNGLCREATEPROGRAMOBJECTARBPROC  ) OpenGL_3::ProcedureAddress( "glCreateProgramObjectARB"  );
	glAttachObjectARB         = ( PFNGLATTACHOBJECTARBPROC         ) OpenGL_3::ProcedureAddress( "glAttachObjectARB"         );
	glLinkProgramARB          = ( PFNGLLINKPROGRAMARBPROC          ) OpenGL_3::ProcedureAddress( "glLinkProgramARB"          );
	glUseProgramObjectARB     = ( PFNGLUSEPROGRAMOBJECTARBPROC     ) OpenGL_3::ProcedureAddress( "glUseProgramObjectARB"     );
	glValidateProgramARB      = ( PFNGLVALIDATEPROGRAMARBPROC      ) OpenGL_3::ProcedureAddress( "glValidateProgramARB"      );
	glUniform1fARB            = ( PFNGLUNIFORM1FARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform1fARB"            );
	glUniform2fARB            = ( PFNGLUNIFORM2FARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform2fARB"            );
	glUniform3fARB            = ( PFNGLUNIFORM3FARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform3fARB"            );
	glUniform4fARB            = ( PFNGLUNIFORM4FARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform4fARB"            );
	glUniform1iARB            = ( PFNGLUNIFORM1IARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform1iARB"            );
	glUniform2iARB            = ( PFNGLUNIFORM2IARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform2iARB"            );
	glUniform3iARB            = ( PFNGLUNIFORM3IARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform3iARB"            );
	glUniform4iARB            = ( PFNGLUNIFORM4IARBPROC            ) OpenGL_3::ProcedureAddress( "glUniform4iARB"            );
	glUniform1fvARB           = ( PFNGLUNIFORM1FVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform1fvARB"           );
	glUniform2fvARB           = ( PFNGLUNIFORM2FVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform2fvARB"           );
	glUniform3fvARB           = ( PFNGLUNIFORM3FVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform3fvARB"           );
	glUniform4fvARB           = ( PFNGLUNIFORM4FVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform4fvARB"           );
	glUniform1ivARB           = ( PFNGLUNIFORM1IVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform1ivARB"           );
	glUniform2ivARB           = ( PFNGLUNIFORM2IVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform2ivARB"           );
	glUniform3ivARB           = ( PFNGLUNIFORM3IVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform3ivARB"           );
	glUniform4ivARB           = ( PFNGLUNIFORM4IVARBPROC           ) OpenGL_3::ProcedureAddress( "glUniform4ivARB"           );
	glUniformMatrix2fvARB     = ( PFNGLUNIFORMMATRIX2FVARBPROC     ) OpenGL_3::ProcedureAddress( "glUniformMatrix2fvARB"     );
	glUniformMatrix3fvARB     = ( PFNGLUNIFORMMATRIX3FVARBPROC     ) OpenGL_3::ProcedureAddress( "glUniformMatrix3fvARB"     );
	glUniformMatrix4fvARB     = ( PFNGLUNIFORMMATRIX4FVARBPROC     ) OpenGL_3::ProcedureAddress( "glUniformMatrix4fvARB"     );
	glGetObjectParameterfvARB = ( PFNGLGETOBJECTPARAMETERFVARBPROC ) OpenGL_3::ProcedureAddress( "glGetObjectParameterfvARB" );
	glGetObjectParameterivARB = ( PFNGLGETOBJECTPARAMETERIVARBPROC ) OpenGL_3::ProcedureAddress( "glGetObjectParameterivARB" );
	glGetInfoLogARB           = ( PFNGLGETINFOLOGARBPROC           ) OpenGL_3::ProcedureAddress( "glGetInfoLogARB"           );
	glGetAttachedObjectsARB   = ( PFNGLGETATTACHEDOBJECTSARBPROC   ) OpenGL_3::ProcedureAddress( "glGetAttachedObjectsARB"   );
	glGetUniformLocationARB   = ( PFNGLGETUNIFORMLOCATIONARBPROC   ) OpenGL_3::ProcedureAddress( "glGetUniformLocationARB"   );
	glGetActiveUniformARB     = ( PFNGLGETACTIVEUNIFORMARBPROC     ) OpenGL_3::ProcedureAddress( "glGetActiveUniformARB"     );
	glGetUniformfvARB         = ( PFNGLGETUNIFORMFVARBPROC         ) OpenGL_3::ProcedureAddress( "glGetUniformfvARB"         );
	glGetUniformivARB         = ( PFNGLGETUNIFORMIVARBPROC         ) OpenGL_3::ProcedureAddress( "glGetUniformivARB"         );
	glGetShaderSourceARB      = ( PFNGLGETSHADERSOURCEARBPROC      ) OpenGL_3::ProcedureAddress( "glGetShaderSourceARB"      );
	glBindAttribLocationARB   = ( PFNGLBINDATTRIBLOCATIONARBPROC   ) OpenGL_3::ProcedureAddress( "glBindAttribLocationARB"   );
	glGetActiveAttribARB      = ( PFNGLGETACTIVEATTRIBARBPROC      ) OpenGL_3::ProcedureAddress( "glGetActiveAttribARB"      );
	glGetAttribLocationARB    = ( PFNGLGETATTRIBLOCATIONARBPROC    ) OpenGL_3::ProcedureAddress( "glGetAttribLocationARB"    );
	glGetVertexAttribfvARB    = ( PFNGLGETVERTEXATTRIBFVARBPROC    ) OpenGL_3::ProcedureAddress( "glGetVertexAttribfvARB"    );

	return ( glDeleteObjectARB != NULL && glGetHandleARB != NULL && glDetachObjectARB != NULL &&
			 glCreateShaderObjectARB != NULL && glShaderSourceARB != NULL && glCompileShaderARB != NULL &&
			 glCreateProgramObjectARB != NULL && glValidateProgramARB != NULL && glUniform1fARB != NULL &&
			 glUniform2fARB != NULL && glUniform3fARB != NULL && glUniform4fARB != NULL &&
			 glUniform1iARB != NULL && glUniform2iARB != NULL && glUniform3iARB != NULL &&
			 glUniform4iARB != NULL && glUniform1fvARB != NULL && glUniform2fvARB != NULL &&
			 glUniform3fvARB != NULL && glUniform4fvARB != NULL && glUniform1ivARB != NULL &&
			 glUniform2ivARB != NULL && glUniform3ivARB != NULL && glUniform4ivARB != NULL &&
			 glUniformMatrix2fvARB != NULL && glUniformMatrix3fvARB != NULL && glUniformMatrix4fvARB != NULL &&
			 glGetObjectParameterfvARB != NULL && glGetObjectParameterivARB != NULL && glGetInfoLogARB != NULL &&
			 glGetAttachedObjectsARB != NULL && glGetUniformLocationARB != NULL && glGetActiveUniformARB != NULL &&
			 glGetUniformfvARB != NULL && glGetUniformivARB != NULL && glGetShaderSourceARB != NULL &&
			 glBindAttribLocationARB != NULL && glGetActiveAttribARB != NULL && glGetAttribLocationARB != NULL &&
			 glGetVertexAttribfvARB != NULL );
}

// инициализация расширений для Vertex Attribs
bool InitVertexAttribs( void )
{
	glVertexAttrib4fARB            = ( PFNGLVERTEXATTRIB4FARBPROC             ) OpenGL_3::ProcedureAddress( "glVertexAttrib4fARB"           );
	glVertexAttrib4fvARB           = ( PFNGLVERTEXATTRIB4FVARBPROC            ) OpenGL_3::ProcedureAddress( "glVertexAttrib4fvARB"          );
	glVertexAttrib3fARB            = ( PFNGLVERTEXATTRIB3FARBPROC             ) OpenGL_3::ProcedureAddress( "glVertexAttrib3fARB"           );
	glVertexAttrib3fvARB           = ( PFNGLVERTEXATTRIB3FVARBPROC            ) OpenGL_3::ProcedureAddress( "glVertexAttrib3fvARB"          );
	glVertexAttribPointerARB       = ( PFNGLVERTEXATTRIBPOINTERARBPROC        ) OpenGL_3::ProcedureAddress( "glVertexAttribPointerARB"      );
	glEnableVertexAttribArrayARB   = ( PFNGLENABLEVERTEXATTRIBARRAYARBPROC    ) OpenGL_3::ProcedureAddress( "glEnableVertexAttribArrayARB"  );
	glDisableVertexAttribArrayARB  = ( PFNGLDISABLEVERTEXATTRIBARRAYARBPROC   ) OpenGL_3::ProcedureAddress( "glDisableVertexAttribArrayARB" );

	return ( NULL != glVertexAttrib4fARB && NULL != glVertexAttrib4fvARB && NULL != glVertexAttrib3fARB &&
			 NULL != glVertexAttrib3fvARB && NULL != glVertexAttribPointerARB && NULL != glEnableVertexAttribArrayARB &&
			 NULL != glDisableVertexAttribArrayARB );
}

// инициализация расширений для VSync
bool InitVSync( void )
{
	wglSwapIntervalEXT    = ( PFNWGLSWAPINTERVALEXTPROC    ) OpenGL_3::ProcedureAddress( "wglSwapIntervalEXT"    );
	wglGetSwapIntervalEXT = ( PFNWGLGETSWAPINTERVALEXTPROC ) OpenGL_3::ProcedureAddress( "wglGetSwapIntervalEXT" );

	return ( NULL != wglSwapIntervalEXT && NULL != wglGetSwapIntervalEXT );
}

// инициализация расширений для FBO
bool InitFBO( void )
{
	glIsRenderbufferEXT                      = ( PFNGLISRENDERBUFFEREXTPROC                      ) OpenGL_3::ProcedureAddress( "glIsRenderbufferEXT"                      );
	glBindRenderbufferEXT                    = ( PFNGLBINDRENDERBUFFEREXTPROC                    ) OpenGL_3::ProcedureAddress( "glBindRenderbufferEXT"                    );
	glDeleteRenderbuffersEXT                 = ( PFNGLDELETERENDERBUFFERSEXTPROC                 ) OpenGL_3::ProcedureAddress( "glDeleteRenderbuffersEXT"                 );
	glGenRenderbuffersEXT                    = ( PFNGLGENRENDERBUFFERSEXTPROC                    ) OpenGL_3::ProcedureAddress( "glGenRenderbuffersEXT"                    );
	glRenderbufferStorageEXT                 = ( PFNGLRENDERBUFFERSTORAGEEXTPROC                 ) OpenGL_3::ProcedureAddress( "glRenderbufferStorageEXT"                 );
	glGetRenderbufferParameterivEXT          = ( PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC          ) OpenGL_3::ProcedureAddress( "glGetRenderbufferParameterivEXT"          );
	glIsFramebufferEXT                       = ( PFNGLISFRAMEBUFFEREXTPROC                       ) OpenGL_3::ProcedureAddress( "glIsFramebufferEXT"                       );
	glBindFramebufferEXT                     = ( PFNGLBINDFRAMEBUFFEREXTPROC                     ) OpenGL_3::ProcedureAddress( "glBindFramebufferEXT"                     );
	glDeleteFramebuffersEXT                  = ( PFNGLDELETEFRAMEBUFFERSEXTPROC                  ) OpenGL_3::ProcedureAddress( "glDeleteFramebuffersEXT"                  );
	glGenFramebuffersEXT                     = ( PFNGLGENFRAMEBUFFERSEXTPROC                     ) OpenGL_3::ProcedureAddress( "glGenFramebuffersEXT"                     );
	glCheckFramebufferStatusEXT              = ( PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC              ) OpenGL_3::ProcedureAddress( "glCheckFramebufferStatusEXT"              );
	glFramebufferTexture1DEXT                = ( PFNGLFRAMEBUFFERTEXTURE1DEXTPROC                ) OpenGL_3::ProcedureAddress( "glFramebufferTexture1DEXT"                );
	glFramebufferTexture2DEXT                = ( PFNGLFRAMEBUFFERTEXTURE2DEXTPROC                ) OpenGL_3::ProcedureAddress( "glFramebufferTexture2DEXT"                );
	glFramebufferTexture3DEXT                = ( PFNGLFRAMEBUFFERTEXTURE3DEXTPROC                ) OpenGL_3::ProcedureAddress( "glFramebufferTexture3DEXT"                );
	glFramebufferRenderbufferEXT             = ( PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC             ) OpenGL_3::ProcedureAddress( "glFramebufferRenderbufferEXT"             );
	glGetFramebufferAttachmentParameterivEXT = ( PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC ) OpenGL_3::ProcedureAddress( "glGetFramebufferAttachmentParameterivEXT" );
	glGenerateMipmapEXT                      = ( PFNGLGENERATEMIPMAPEXTPROC					     ) OpenGL_3::ProcedureAddress( "glGenerateMipmapEXT"                      );

	return ( NULL != glIsRenderbufferEXT && NULL != glBindRenderbufferEXT && NULL != glDeleteRenderbuffersEXT &&
			 NULL != glGenRenderbuffersEXT && NULL != glRenderbufferStorageEXT && NULL != glGetRenderbufferParameterivEXT &&
			 NULL != glIsFramebufferEXT && NULL != glBindFramebufferEXT && NULL != glDeleteFramebuffersEXT &&
			 NULL != glGenFramebuffersEXT && NULL != glCheckFramebufferStatusEXT && NULL != glFramebufferTexture1DEXT &&
			 NULL != glFramebufferTexture2DEXT && NULL != glFramebufferTexture3DEXT && NULL != glFramebufferRenderbufferEXT &&
			 NULL != glGetFramebufferAttachmentParameterivEXT && NULL != glGenerateMipmapEXT );
}

// инициализация расширения для раздельных blend-factors по RGB и ALPHA
bool InitBlendFuncSeparate( void )
{
	glBlendFuncSeparateEXT     = ( PFNGLBLENDFUNCSEPARATEPROC        ) OpenGL_3::ProcedureAddress( "glBlendFuncSeparateEXT" );
	glBlendEquationSeparateEXT = ( PFNGLBLENDEQUATIONSEPARATEEXTPROC ) OpenGL_3::ProcedureAddress( "glBlendEquationSeparateEXT" );
	glBlendEquationEXT         = ( PFNGLBLENDEQUATIONEXTPROC         ) OpenGL_3::ProcedureAddress( "glBlendEquationEXT" );
	return ( NULL != glBlendFuncSeparateEXT && NULL != glBlendEquationEXT && NULL != glBlendEquationSeparateEXT );
}

}; // namespace glext
