// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include <sstream>
#include <unordered_map>

#include "Common/GL/GLInterfaceBase.h"
#include "Common/GL/GLExtensions/GLExtensions.h"
#include "Common/Logging/Log.h"


#if defined(__linux__) || defined(__APPLE__)
#include <dlfcn.h>
#endif

// gl_1_1
PFNDOLCLEARINDEXPROC dolClearIndex;
PFNDOLCLEARCOLORPROC dolClearColor;
PFNDOLCLEARPROC dolClear;
PFNDOLINDEXMASKPROC dolIndexMask;
PFNDOLCOLORMASKPROC dolColorMask;
PFNDOLALPHAFUNCPROC dolAlphaFunc;
PFNDOLBLENDFUNCPROC dolBlendFunc;
PFNDOLLOGICOPPROC dolLogicOp;
PFNDOLCULLFACEPROC dolCullFace;
PFNDOLFRONTFACEPROC dolFrontFace;
PFNDOLPOINTSIZEPROC dolPointSize;
PFNDOLLINEWIDTHPROC dolLineWidth;
PFNDOLLINESTIPPLEPROC dolLineStipple;
PFNDOLPOLYGONMODEPROC dolPolygonMode;
PFNDOLPOLYGONOFFSETPROC dolPolygonOffset;
PFNDOLPOLYGONSTIPPLEPROC dolPolygonStipple;
PFNDOLGETPOLYGONSTIPPLEPROC dolGetPolygonStipple;
PFNDOLEDGEFLAGPROC dolEdgeFlag;
PFNDOLEDGEFLAGVPROC dolEdgeFlagv;
PFNDOLSCISSORPROC dolScissor;
PFNDOLCLIPPLANEPROC dolClipPlane;
PFNDOLGETCLIPPLANEPROC dolGetClipPlane;
PFNDOLDRAWBUFFERPROC dolDrawBuffer;
PFNDOLREADBUFFERPROC dolReadBuffer;
PFNDOLENABLEPROC dolEnable;
PFNDOLDISABLEPROC dolDisable;
PFNDOLISENABLEDPROC dolIsEnabled;
PFNDOLENABLECLIENTSTATEPROC dolEnableClientState;
PFNDOLDISABLECLIENTSTATEPROC dolDisableClientState;
PFNDOLGETBOOLEANVPROC dolGetBooleanv;
PFNDOLGETDOUBLEVPROC dolGetDoublev;
PFNDOLGETFLOATVPROC dolGetFloatv;
PFNDOLGETINTEGERVPROC dolGetIntegerv;
PFNDOLPUSHATTRIBPROC dolPushAttrib;
PFNDOLPOPATTRIBPROC dolPopAttrib;
PFNDOLPUSHCLIENTATTRIBPROC dolPushClientAttrib;
PFNDOLPOPCLIENTATTRIBPROC dolPopClientAttrib;
PFNDOLRENDERMODEPROC dolRenderMode;
PFNDOLGETERRORPROC dolGetError;
PFNDOLGETSTRINGPROC dolGetString;
PFNDOLFINISHPROC dolFinish;
PFNDOLFLUSHPROC dolFlush;
PFNDOLHINTPROC dolHint;
PFNDOLCLEARDEPTHPROC dolClearDepth;
PFNDOLDEPTHFUNCPROC dolDepthFunc;
PFNDOLDEPTHMASKPROC dolDepthMask;
PFNDOLDEPTHRANGEPROC dolDepthRange;
PFNDOLCLEARACCUMPROC dolClearAccum;
PFNDOLACCUMPROC dolAccum;
PFNDOLMATRIXMODEPROC dolMatrixMode;
PFNDOLORTHOPROC dolOrtho;
PFNDOLFRUSTUMPROC dolFrustum;
PFNDOLVIEWPORTPROC dolViewport;
PFNDOLPUSHMATRIXPROC dolPushMatrix;
PFNDOLPOPMATRIXPROC dolPopMatrix;
PFNDOLLOADIDENTITYPROC dolLoadIdentity;
PFNDOLLOADMATRIXDPROC dolLoadMatrixd;
PFNDOLLOADMATRIXFPROC dolLoadMatrixf;
PFNDOLMULTMATRIXDPROC dolMultMatrixd;
PFNDOLMULTMATRIXFPROC dolMultMatrixf;
PFNDOLROTATEDPROC dolRotated;
PFNDOLROTATEFPROC dolRotatef;
PFNDOLSCALEDPROC dolScaled;
PFNDOLSCALEFPROC dolScalef;
PFNDOLTRANSLATEDPROC dolTranslated;
PFNDOLTRANSLATEFPROC dolTranslatef;
PFNDOLISLISTPROC dolIsList;
PFNDOLDELETELISTSPROC dolDeleteLists;
PFNDOLGENLISTSPROC dolGenLists;
PFNDOLNEWLISTPROC dolNewList;
PFNDOLENDLISTPROC dolEndList;
PFNDOLCALLLISTPROC dolCallList;
PFNDOLCALLLISTSPROC dolCallLists;
PFNDOLLISTBASEPROC dolListBase;
PFNDOLBEGINPROC dolBegin;
PFNDOLENDPROC dolEnd;
PFNDOLVERTEX2DPROC dolVertex2d;
PFNDOLVERTEX2FPROC dolVertex2f;
PFNDOLVERTEX2IPROC dolVertex2i;
PFNDOLVERTEX2SPROC dolVertex2s;
PFNDOLVERTEX3DPROC dolVertex3d;
PFNDOLVERTEX3FPROC dolVertex3f;
PFNDOLVERTEX3IPROC dolVertex3i;
PFNDOLVERTEX3SPROC dolVertex3s;
PFNDOLVERTEX4DPROC dolVertex4d;
PFNDOLVERTEX4FPROC dolVertex4f;
PFNDOLVERTEX4IPROC dolVertex4i;
PFNDOLVERTEX4SPROC dolVertex4s;
PFNDOLVERTEX2DVPROC dolVertex2dv;
PFNDOLVERTEX2FVPROC dolVertex2fv;
PFNDOLVERTEX2IVPROC dolVertex2iv;
PFNDOLVERTEX2SVPROC dolVertex2sv;
PFNDOLVERTEX3DVPROC dolVertex3dv;
PFNDOLVERTEX3FVPROC dolVertex3fv;
PFNDOLVERTEX3IVPROC dolVertex3iv;
PFNDOLVERTEX3SVPROC dolVertex3sv;
PFNDOLVERTEX4DVPROC dolVertex4dv;
PFNDOLVERTEX4FVPROC dolVertex4fv;
PFNDOLVERTEX4IVPROC dolVertex4iv;
PFNDOLVERTEX4SVPROC dolVertex4sv;
PFNDOLNORMAL3BPROC dolNormal3b;
PFNDOLNORMAL3DPROC dolNormal3d;
PFNDOLNORMAL3FPROC dolNormal3f;
PFNDOLNORMAL3IPROC dolNormal3i;
PFNDOLNORMAL3SPROC dolNormal3s;
PFNDOLNORMAL3BVPROC dolNormal3bv;
PFNDOLNORMAL3DVPROC dolNormal3dv;
PFNDOLNORMAL3FVPROC dolNormal3fv;
PFNDOLNORMAL3IVPROC dolNormal3iv;
PFNDOLNORMAL3SVPROC dolNormal3sv;
PFNDOLINDEXDPROC dolIndexd;
PFNDOLINDEXFPROC dolIndexf;
PFNDOLINDEXIPROC dolIndexi;
PFNDOLINDEXSPROC dolIndexs;
PFNDOLINDEXUBPROC dolIndexub;
PFNDOLINDEXDVPROC dolIndexdv;
PFNDOLINDEXFVPROC dolIndexfv;
PFNDOLINDEXIVPROC dolIndexiv;
PFNDOLINDEXSVPROC dolIndexsv;
PFNDOLINDEXUBVPROC dolIndexubv;
PFNDOLCOLOR3BPROC dolColor3b;
PFNDOLCOLOR3DPROC dolColor3d;
PFNDOLCOLOR3FPROC dolColor3f;
PFNDOLCOLOR3IPROC dolColor3i;
PFNDOLCOLOR3SPROC dolColor3s;
PFNDOLCOLOR3UBPROC dolColor3ub;
PFNDOLCOLOR3UIPROC dolColor3ui;
PFNDOLCOLOR3USPROC dolColor3us;
PFNDOLCOLOR4BPROC dolColor4b;
PFNDOLCOLOR4DPROC dolColor4d;
PFNDOLCOLOR4FPROC dolColor4f;
PFNDOLCOLOR4IPROC dolColor4i;
PFNDOLCOLOR4SPROC dolColor4s;
PFNDOLCOLOR4UBPROC dolColor4ub;
PFNDOLCOLOR4UIPROC dolColor4ui;
PFNDOLCOLOR4USPROC dolColor4us;
PFNDOLCOLOR3BVPROC dolColor3bv;
PFNDOLCOLOR3DVPROC dolColor3dv;
PFNDOLCOLOR3FVPROC dolColor3fv;
PFNDOLCOLOR3IVPROC dolColor3iv;
PFNDOLCOLOR3SVPROC dolColor3sv;
PFNDOLCOLOR3UBVPROC dolColor3ubv;
PFNDOLCOLOR3UIVPROC dolColor3uiv;
PFNDOLCOLOR3USVPROC dolColor3usv;
PFNDOLCOLOR4BVPROC dolColor4bv;
PFNDOLCOLOR4DVPROC dolColor4dv;
PFNDOLCOLOR4FVPROC dolColor4fv;
PFNDOLCOLOR4IVPROC dolColor4iv;
PFNDOLCOLOR4SVPROC dolColor4sv;
PFNDOLCOLOR4UBVPROC dolColor4ubv;
PFNDOLCOLOR4UIVPROC dolColor4uiv;
PFNDOLCOLOR4USVPROC dolColor4usv;
PFNDOLTEXCOORD1DPROC dolTexCoord1d;
PFNDOLTEXCOORD1FPROC dolTexCoord1f;
PFNDOLTEXCOORD1IPROC dolTexCoord1i;
PFNDOLTEXCOORD1SPROC dolTexCoord1s;
PFNDOLTEXCOORD2DPROC dolTexCoord2d;
PFNDOLTEXCOORD2FPROC dolTexCoord2f;
PFNDOLTEXCOORD2IPROC dolTexCoord2i;
PFNDOLTEXCOORD2SPROC dolTexCoord2s;
PFNDOLTEXCOORD3DPROC dolTexCoord3d;
PFNDOLTEXCOORD3FPROC dolTexCoord3f;
PFNDOLTEXCOORD3IPROC dolTexCoord3i;
PFNDOLTEXCOORD3SPROC dolTexCoord3s;
PFNDOLTEXCOORD4DPROC dolTexCoord4d;
PFNDOLTEXCOORD4FPROC dolTexCoord4f;
PFNDOLTEXCOORD4IPROC dolTexCoord4i;
PFNDOLTEXCOORD4SPROC dolTexCoord4s;
PFNDOLTEXCOORD1DVPROC dolTexCoord1dv;
PFNDOLTEXCOORD1FVPROC dolTexCoord1fv;
PFNDOLTEXCOORD1IVPROC dolTexCoord1iv;
PFNDOLTEXCOORD1SVPROC dolTexCoord1sv;
PFNDOLTEXCOORD2DVPROC dolTexCoord2dv;
PFNDOLTEXCOORD2FVPROC dolTexCoord2fv;
PFNDOLTEXCOORD2IVPROC dolTexCoord2iv;
PFNDOLTEXCOORD2SVPROC dolTexCoord2sv;
PFNDOLTEXCOORD3DVPROC dolTexCoord3dv;
PFNDOLTEXCOORD3FVPROC dolTexCoord3fv;
PFNDOLTEXCOORD3IVPROC dolTexCoord3iv;
PFNDOLTEXCOORD3SVPROC dolTexCoord3sv;
PFNDOLTEXCOORD4DVPROC dolTexCoord4dv;
PFNDOLTEXCOORD4FVPROC dolTexCoord4fv;
PFNDOLTEXCOORD4IVPROC dolTexCoord4iv;
PFNDOLTEXCOORD4SVPROC dolTexCoord4sv;
PFNDOLRASTERPOS2DPROC dolRasterPos2d;
PFNDOLRASTERPOS2FPROC dolRasterPos2f;
PFNDOLRASTERPOS2IPROC dolRasterPos2i;
PFNDOLRASTERPOS2SPROC dolRasterPos2s;
PFNDOLRASTERPOS3DPROC dolRasterPos3d;
PFNDOLRASTERPOS3FPROC dolRasterPos3f;
PFNDOLRASTERPOS3IPROC dolRasterPos3i;
PFNDOLRASTERPOS3SPROC dolRasterPos3s;
PFNDOLRASTERPOS4DPROC dolRasterPos4d;
PFNDOLRASTERPOS4FPROC dolRasterPos4f;
PFNDOLRASTERPOS4IPROC dolRasterPos4i;
PFNDOLRASTERPOS4SPROC dolRasterPos4s;
PFNDOLRASTERPOS2DVPROC dolRasterPos2dv;
PFNDOLRASTERPOS2FVPROC dolRasterPos2fv;
PFNDOLRASTERPOS2IVPROC dolRasterPos2iv;
PFNDOLRASTERPOS2SVPROC dolRasterPos2sv;
PFNDOLRASTERPOS3DVPROC dolRasterPos3dv;
PFNDOLRASTERPOS3FVPROC dolRasterPos3fv;
PFNDOLRASTERPOS3IVPROC dolRasterPos3iv;
PFNDOLRASTERPOS3SVPROC dolRasterPos3sv;
PFNDOLRASTERPOS4DVPROC dolRasterPos4dv;
PFNDOLRASTERPOS4FVPROC dolRasterPos4fv;
PFNDOLRASTERPOS4IVPROC dolRasterPos4iv;
PFNDOLRASTERPOS4SVPROC dolRasterPos4sv;
PFNDOLRECTDPROC dolRectd;
PFNDOLRECTFPROC dolRectf;
PFNDOLRECTIPROC dolRecti;
PFNDOLRECTSPROC dolRects;
PFNDOLRECTDVPROC dolRectdv;
PFNDOLRECTFVPROC dolRectfv;
PFNDOLRECTIVPROC dolRectiv;
PFNDOLRECTSVPROC dolRectsv;
PFNDOLVERTEXPOINTERPROC dolVertexPointer;
PFNDOLNORMALPOINTERPROC dolNormalPointer;
PFNDOLCOLORPOINTERPROC dolColorPointer;
PFNDOLINDEXPOINTERPROC dolIndexPointer;
PFNDOLTEXCOORDPOINTERPROC dolTexCoordPointer;
PFNDOLEDGEFLAGPOINTERPROC dolEdgeFlagPointer;
PFNDOLGETPOINTERVPROC dolGetPointerv;
PFNDOLARRAYELEMENTPROC dolArrayElement;
PFNDOLDRAWARRAYSPROC dolDrawArrays;
PFNDOLDRAWELEMENTSPROC dolDrawElements;
PFNDOLINTERLEAVEDARRAYSPROC dolInterleavedArrays;
PFNDOLSHADEMODELPROC dolShadeModel;
PFNDOLLIGHTFPROC dolLightf;
PFNDOLLIGHTIPROC dolLighti;
PFNDOLLIGHTFVPROC dolLightfv;
PFNDOLLIGHTIVPROC dolLightiv;
PFNDOLGETLIGHTFVPROC dolGetLightfv;
PFNDOLGETLIGHTIVPROC dolGetLightiv;
PFNDOLLIGHTMODELFPROC dolLightModelf;
PFNDOLLIGHTMODELIPROC dolLightModeli;
PFNDOLLIGHTMODELFVPROC dolLightModelfv;
PFNDOLLIGHTMODELIVPROC dolLightModeliv;
PFNDOLMATERIALFPROC dolMaterialf;
PFNDOLMATERIALIPROC dolMateriali;
PFNDOLMATERIALFVPROC dolMaterialfv;
PFNDOLMATERIALIVPROC dolMaterialiv;
PFNDOLGETMATERIALFVPROC dolGetMaterialfv;
PFNDOLGETMATERIALIVPROC dolGetMaterialiv;
PFNDOLCOLORMATERIALPROC dolColorMaterial;
PFNDOLPIXELZOOMPROC dolPixelZoom;
PFNDOLPIXELSTOREFPROC dolPixelStoref;
PFNDOLPIXELSTOREIPROC dolPixelStorei;
PFNDOLPIXELTRANSFERFPROC dolPixelTransferf;
PFNDOLPIXELTRANSFERIPROC dolPixelTransferi;
PFNDOLPIXELMAPFVPROC dolPixelMapfv;
PFNDOLPIXELMAPUIVPROC dolPixelMapuiv;
PFNDOLPIXELMAPUSVPROC dolPixelMapusv;
PFNDOLGETPIXELMAPFVPROC dolGetPixelMapfv;
PFNDOLGETPIXELMAPUIVPROC dolGetPixelMapuiv;
PFNDOLGETPIXELMAPUSVPROC dolGetPixelMapusv;
PFNDOLBITMAPPROC dolBitmap;
PFNDOLREADPIXELSPROC dolReadPixels;
PFNDOLDRAWPIXELSPROC dolDrawPixels;
PFNDOLCOPYPIXELSPROC dolCopyPixels;
PFNDOLSTENCILFUNCPROC dolStencilFunc;
PFNDOLSTENCILMASKPROC dolStencilMask;
PFNDOLSTENCILOPPROC dolStencilOp;
PFNDOLCLEARSTENCILPROC dolClearStencil;
PFNDOLTEXGENDPROC dolTexGend;
PFNDOLTEXGENFPROC dolTexGenf;
PFNDOLTEXGENIPROC dolTexGeni;
PFNDOLTEXGENDVPROC dolTexGendv;
PFNDOLTEXGENFVPROC dolTexGenfv;
PFNDOLTEXGENIVPROC dolTexGeniv;
PFNDOLGETTEXGENDVPROC dolGetTexGendv;
PFNDOLGETTEXGENFVPROC dolGetTexGenfv;
PFNDOLGETTEXGENIVPROC dolGetTexGeniv;
PFNDOLTEXENVFPROC dolTexEnvf;
PFNDOLTEXENVIPROC dolTexEnvi;
PFNDOLTEXENVFVPROC dolTexEnvfv;
PFNDOLTEXENVIVPROC dolTexEnviv;
PFNDOLGETTEXENVFVPROC dolGetTexEnvfv;
PFNDOLGETTEXENVIVPROC dolGetTexEnviv;
PFNDOLTEXPARAMETERFPROC dolTexParameterf;
PFNDOLTEXPARAMETERIPROC dolTexParameteri;
PFNDOLTEXPARAMETERFVPROC dolTexParameterfv;
PFNDOLTEXPARAMETERIVPROC dolTexParameteriv;
PFNDOLGETTEXPARAMETERFVPROC dolGetTexParameterfv;
PFNDOLGETTEXPARAMETERIVPROC dolGetTexParameteriv;
PFNDOLGETTEXLEVELPARAMETERFVPROC dolGetTexLevelParameterfv;
PFNDOLGETTEXLEVELPARAMETERIVPROC dolGetTexLevelParameteriv;
PFNDOLTEXIMAGE1DPROC dolTexImage1D;
PFNDOLTEXIMAGE2DPROC dolTexImage2D;
PFNDOLGETTEXIMAGEPROC dolGetTexImage;
PFNDOLGENTEXTURESPROC dolGenTextures;
PFNDOLDELETETEXTURESPROC dolDeleteTextures;
PFNDOLBINDTEXTUREPROC dolBindTexture;
PFNDOLPRIORITIZETEXTURESPROC dolPrioritizeTextures;
PFNDOLARETEXTURESRESIDENTPROC dolAreTexturesResident;
PFNDOLISTEXTUREPROC dolIsTexture;
PFNDOLTEXSUBIMAGE1DPROC dolTexSubImage1D;
PFNDOLTEXSUBIMAGE2DPROC dolTexSubImage2D;
PFNDOLCOPYTEXIMAGE1DPROC dolCopyTexImage1D;
PFNDOLCOPYTEXIMAGE2DPROC dolCopyTexImage2D;
PFNDOLCOPYTEXSUBIMAGE1DPROC dolCopyTexSubImage1D;
PFNDOLCOPYTEXSUBIMAGE2DPROC dolCopyTexSubImage2D;
PFNDOLMAP1DPROC dolMap1d;
PFNDOLMAP1FPROC dolMap1f;
PFNDOLMAP2DPROC dolMap2d;
PFNDOLMAP2FPROC dolMap2f;
PFNDOLGETMAPDVPROC dolGetMapdv;
PFNDOLGETMAPFVPROC dolGetMapfv;
PFNDOLGETMAPIVPROC dolGetMapiv;
PFNDOLEVALCOORD1DPROC dolEvalCoord1d;
PFNDOLEVALCOORD1FPROC dolEvalCoord1f;
PFNDOLEVALCOORD1DVPROC dolEvalCoord1dv;
PFNDOLEVALCOORD1FVPROC dolEvalCoord1fv;
PFNDOLEVALCOORD2DPROC dolEvalCoord2d;
PFNDOLEVALCOORD2FPROC dolEvalCoord2f;
PFNDOLEVALCOORD2DVPROC dolEvalCoord2dv;
PFNDOLEVALCOORD2FVPROC dolEvalCoord2fv;
PFNDOLMAPGRID1DPROC dolMapGrid1d;
PFNDOLMAPGRID1FPROC dolMapGrid1f;
PFNDOLMAPGRID2DPROC dolMapGrid2d;
PFNDOLMAPGRID2FPROC dolMapGrid2f;
PFNDOLEVALPOINT1PROC dolEvalPoint1;
PFNDOLEVALPOINT2PROC dolEvalPoint2;
PFNDOLEVALMESH1PROC dolEvalMesh1;
PFNDOLEVALMESH2PROC dolEvalMesh2;
PFNDOLFOGFPROC dolFogf;
PFNDOLFOGIPROC dolFogi;
PFNDOLFOGFVPROC dolFogfv;
PFNDOLFOGIVPROC dolFogiv;
PFNDOLFEEDBACKBUFFERPROC dolFeedbackBuffer;
PFNDOLPASSTHROUGHPROC dolPassThrough;
PFNDOLSELECTBUFFERPROC dolSelectBuffer;
PFNDOLINITNAMESPROC dolInitNames;
PFNDOLLOADNAMEPROC dolLoadName;
PFNDOLPUSHNAMEPROC dolPushName;
PFNDOLPOPNAMEPROC dolPopName;

// gl_1_2
PFNDOLCOPYTEXSUBIMAGE3DPROC dolCopyTexSubImage3D;
PFNDOLDRAWRANGEELEMENTSPROC dolDrawRangeElements;
PFNDOLTEXIMAGE3DPROC dolTexImage3D;
PFNDOLTEXSUBIMAGE3DPROC dolTexSubImage3D;

// gl_1_3
PFNDOLACTIVETEXTUREARBPROC dolActiveTexture;
PFNDOLCLIENTACTIVETEXTUREARBPROC dolClientActiveTexture;
PFNDOLCOMPRESSEDTEXIMAGE1DPROC dolCompressedTexImage1D;
PFNDOLCOMPRESSEDTEXIMAGE2DPROC dolCompressedTexImage2D;
PFNDOLCOMPRESSEDTEXIMAGE3DPROC dolCompressedTexImage3D;
PFNDOLCOMPRESSEDTEXSUBIMAGE1DPROC dolCompressedTexSubImage1D;
PFNDOLCOMPRESSEDTEXSUBIMAGE2DPROC dolCompressedTexSubImage2D;
PFNDOLCOMPRESSEDTEXSUBIMAGE3DPROC dolCompressedTexSubImage3D;
PFNDOLGETCOMPRESSEDTEXIMAGEPROC dolGetCompressedTexImage;
PFNDOLLOADTRANSPOSEMATRIXDARBPROC dolLoadTransposeMatrixd;
PFNDOLLOADTRANSPOSEMATRIXFARBPROC dolLoadTransposeMatrixf;
PFNDOLMULTTRANSPOSEMATRIXDARBPROC dolMultTransposeMatrixd;
PFNDOLMULTTRANSPOSEMATRIXFARBPROC dolMultTransposeMatrixf;
PFNDOLMULTITEXCOORD1DARBPROC dolMultiTexCoord1d;
PFNDOLMULTITEXCOORD1DVARBPROC dolMultiTexCoord1dv;
PFNDOLMULTITEXCOORD1FARBPROC dolMultiTexCoord1f;
PFNDOLMULTITEXCOORD1FVARBPROC dolMultiTexCoord1fv;
PFNDOLMULTITEXCOORD1IARBPROC dolMultiTexCoord1i;
PFNDOLMULTITEXCOORD1IVARBPROC dolMultiTexCoord1iv;
PFNDOLMULTITEXCOORD1SARBPROC dolMultiTexCoord1s;
PFNDOLMULTITEXCOORD1SVARBPROC dolMultiTexCoord1sv;
PFNDOLMULTITEXCOORD2DARBPROC dolMultiTexCoord2d;
PFNDOLMULTITEXCOORD2DVARBPROC dolMultiTexCoord2dv;
PFNDOLMULTITEXCOORD2FARBPROC dolMultiTexCoord2f;
PFNDOLMULTITEXCOORD2FVARBPROC dolMultiTexCoord2fv;
PFNDOLMULTITEXCOORD2IARBPROC dolMultiTexCoord2i;
PFNDOLMULTITEXCOORD2IVARBPROC dolMultiTexCoord2iv;
PFNDOLMULTITEXCOORD2SARBPROC dolMultiTexCoord2s;
PFNDOLMULTITEXCOORD2SVARBPROC dolMultiTexCoord2sv;
PFNDOLMULTITEXCOORD3DARBPROC dolMultiTexCoord3d;
PFNDOLMULTITEXCOORD3DVARBPROC dolMultiTexCoord3dv;
PFNDOLMULTITEXCOORD3FARBPROC dolMultiTexCoord3f;
PFNDOLMULTITEXCOORD3FVARBPROC dolMultiTexCoord3fv;
PFNDOLMULTITEXCOORD3IARBPROC dolMultiTexCoord3i;
PFNDOLMULTITEXCOORD3IVARBPROC dolMultiTexCoord3iv;
PFNDOLMULTITEXCOORD3SARBPROC dolMultiTexCoord3s;
PFNDOLMULTITEXCOORD3SVARBPROC dolMultiTexCoord3sv;
PFNDOLMULTITEXCOORD4DARBPROC dolMultiTexCoord4d;
PFNDOLMULTITEXCOORD4DVARBPROC dolMultiTexCoord4dv;
PFNDOLMULTITEXCOORD4FARBPROC dolMultiTexCoord4f;
PFNDOLMULTITEXCOORD4FVARBPROC dolMultiTexCoord4fv;
PFNDOLMULTITEXCOORD4IARBPROC dolMultiTexCoord4i;
PFNDOLMULTITEXCOORD4IVARBPROC dolMultiTexCoord4iv;
PFNDOLMULTITEXCOORD4SARBPROC dolMultiTexCoord4s;
PFNDOLMULTITEXCOORD4SVARBPROC dolMultiTexCoord4sv;
PFNDOLSAMPLECOVERAGEARBPROC dolSampleCoverage;

// gl_1_4
PFNDOLBLENDCOLORPROC dolBlendColor;
PFNDOLBLENDEQUATIONPROC dolBlendEquation;
PFNDOLBLENDFUNCSEPARATEPROC dolBlendFuncSeparate;
PFNDOLFOGCOORDPOINTERPROC dolFogCoordPointer;
PFNDOLFOGCOORDDPROC dolFogCoordd;
PFNDOLFOGCOORDDVPROC dolFogCoorddv;
PFNDOLFOGCOORDFPROC dolFogCoordf;
PFNDOLFOGCOORDFVPROC dolFogCoordfv;
PFNDOLMULTIDRAWARRAYSPROC dolMultiDrawArrays;
PFNDOLMULTIDRAWELEMENTSPROC dolMultiDrawElements;
PFNDOLPOINTPARAMETERFPROC dolPointParameterf;
PFNDOLPOINTPARAMETERFVPROC dolPointParameterfv;
PFNDOLPOINTPARAMETERIPROC dolPointParameteri;
PFNDOLPOINTPARAMETERIVPROC dolPointParameteriv;
PFNDOLSECONDARYCOLOR3BPROC dolSecondaryColor3b;
PFNDOLSECONDARYCOLOR3BVPROC dolSecondaryColor3bv;
PFNDOLSECONDARYCOLOR3DPROC dolSecondaryColor3d;
PFNDOLSECONDARYCOLOR3DVPROC dolSecondaryColor3dv;
PFNDOLSECONDARYCOLOR3FPROC dolSecondaryColor3f;
PFNDOLSECONDARYCOLOR3FVPROC dolSecondaryColor3fv;
PFNDOLSECONDARYCOLOR3IPROC dolSecondaryColor3i;
PFNDOLSECONDARYCOLOR3IVPROC dolSecondaryColor3iv;
PFNDOLSECONDARYCOLOR3SPROC dolSecondaryColor3s;
PFNDOLSECONDARYCOLOR3SVPROC dolSecondaryColor3sv;
PFNDOLSECONDARYCOLOR3UBPROC dolSecondaryColor3ub;
PFNDOLSECONDARYCOLOR3UBVPROC dolSecondaryColor3ubv;
PFNDOLSECONDARYCOLOR3UIPROC dolSecondaryColor3ui;
PFNDOLSECONDARYCOLOR3UIVPROC dolSecondaryColor3uiv;
PFNDOLSECONDARYCOLOR3USPROC dolSecondaryColor3us;
PFNDOLSECONDARYCOLOR3USVPROC dolSecondaryColor3usv;
PFNDOLSECONDARYCOLORPOINTERPROC dolSecondaryColorPointer;
PFNDOLWINDOWPOS2DPROC dolWindowPos2d;
PFNDOLWINDOWPOS2DVPROC dolWindowPos2dv;
PFNDOLWINDOWPOS2FPROC dolWindowPos2f;
PFNDOLWINDOWPOS2FVPROC dolWindowPos2fv;
PFNDOLWINDOWPOS2IPROC dolWindowPos2i;
PFNDOLWINDOWPOS2IVPROC dolWindowPos2iv;
PFNDOLWINDOWPOS2SPROC dolWindowPos2s;
PFNDOLWINDOWPOS2SVPROC dolWindowPos2sv;
PFNDOLWINDOWPOS3DPROC dolWindowPos3d;
PFNDOLWINDOWPOS3DVPROC dolWindowPos3dv;
PFNDOLWINDOWPOS3FPROC dolWindowPos3f;
PFNDOLWINDOWPOS3FVPROC dolWindowPos3fv;
PFNDOLWINDOWPOS3IPROC dolWindowPos3i;
PFNDOLWINDOWPOS3IVPROC dolWindowPos3iv;
PFNDOLWINDOWPOS3SPROC dolWindowPos3s;
PFNDOLWINDOWPOS3SVPROC dolWindowPos3sv;

// gl_1_5
PFNDOLBEGINQUERYPROC dolBeginQuery;
PFNDOLBINDBUFFERPROC dolBindBuffer;
PFNDOLBUFFERDATAPROC dolBufferData;
PFNDOLBUFFERSUBDATAPROC dolBufferSubData;
PFNDOLDELETEBUFFERSPROC dolDeleteBuffers;
PFNDOLDELETEQUERIESPROC dolDeleteQueries;
PFNDOLENDQUERYPROC dolEndQuery;
PFNDOLGENBUFFERSPROC dolGenBuffers;
PFNDOLGENQUERIESPROC dolGenQueries;
PFNDOLGETBUFFERPARAMETERIVPROC dolGetBufferParameteriv;
PFNDOLGETBUFFERPOINTERVPROC dolGetBufferPointerv;
PFNDOLGETBUFFERSUBDATAPROC dolGetBufferSubData;
PFNDOLGETQUERYOBJECTIVPROC dolGetQueryObjectiv;
PFNDOLGETQUERYOBJECTUIVPROC dolGetQueryObjectuiv;
PFNDOLGETQUERYIVPROC dolGetQueryiv;
PFNDOLISBUFFERPROC dolIsBuffer;
PFNDOLISQUERYPROC dolIsQuery;
PFNDOLMAPBUFFERPROC dolMapBuffer;
PFNDOLUNMAPBUFFERPROC dolUnmapBuffer;

// gl_2_0
PFNDOLATTACHSHADERPROC dolAttachShader;
PFNDOLBINDATTRIBLOCATIONPROC dolBindAttribLocation;
PFNDOLBLENDEQUATIONSEPARATEPROC dolBlendEquationSeparate;
PFNDOLCOMPILESHADERPROC dolCompileShader;
PFNDOLCREATEPROGRAMPROC dolCreateProgram;
PFNDOLCREATESHADERPROC dolCreateShader;
PFNDOLDELETEPROGRAMPROC dolDeleteProgram;
PFNDOLDELETESHADERPROC dolDeleteShader;
PFNDOLDETACHSHADERPROC dolDetachShader;
PFNDOLDISABLEVERTEXATTRIBARRAYPROC dolDisableVertexAttribArray;
PFNDOLDRAWBUFFERSPROC dolDrawBuffers;
PFNDOLENABLEVERTEXATTRIBARRAYPROC dolEnableVertexAttribArray;
PFNDOLGETACTIVEATTRIBPROC dolGetActiveAttrib;
PFNDOLGETACTIVEUNIFORMPROC dolGetActiveUniform;
PFNDOLGETATTACHEDSHADERSPROC dolGetAttachedShaders;
PFNDOLGETATTRIBLOCATIONPROC dolGetAttribLocation;
PFNDOLGETPROGRAMINFOLOGPROC dolGetProgramInfoLog;
PFNDOLGETPROGRAMIVPROC dolGetProgramiv;
PFNDOLGETSHADERINFOLOGPROC dolGetShaderInfoLog;
PFNDOLGETSHADERSOURCEPROC dolGetShaderSource;
PFNDOLGETSHADERIVPROC dolGetShaderiv;
PFNDOLGETUNIFORMLOCATIONPROC dolGetUniformLocation;
PFNDOLGETUNIFORMFVPROC dolGetUniformfv;
PFNDOLGETUNIFORMIVPROC dolGetUniformiv;
PFNDOLGETVERTEXATTRIBPOINTERVPROC dolGetVertexAttribPointerv;
PFNDOLGETVERTEXATTRIBDVPROC dolGetVertexAttribdv;
PFNDOLGETVERTEXATTRIBFVPROC dolGetVertexAttribfv;
PFNDOLGETVERTEXATTRIBIVPROC dolGetVertexAttribiv;
PFNDOLISPROGRAMPROC dolIsProgram;
PFNDOLISSHADERPROC dolIsShader;
PFNDOLLINKPROGRAMPROC dolLinkProgram;
PFNDOLSHADERSOURCEPROC dolShaderSource;
PFNDOLSTENCILFUNCSEPARATEPROC dolStencilFuncSeparate;
PFNDOLSTENCILMASKSEPARATEPROC dolStencilMaskSeparate;
PFNDOLSTENCILOPSEPARATEPROC dolStencilOpSeparate;
PFNDOLUNIFORM1FPROC dolUniform1f;
PFNDOLUNIFORM1FVPROC dolUniform1fv;
PFNDOLUNIFORM1IPROC dolUniform1i;
PFNDOLUNIFORM1IVPROC dolUniform1iv;
PFNDOLUNIFORM2FPROC dolUniform2f;
PFNDOLUNIFORM2FVPROC dolUniform2fv;
PFNDOLUNIFORM2IPROC dolUniform2i;
PFNDOLUNIFORM2IVPROC dolUniform2iv;
PFNDOLUNIFORM3FPROC dolUniform3f;
PFNDOLUNIFORM3FVPROC dolUniform3fv;
PFNDOLUNIFORM3IPROC dolUniform3i;
PFNDOLUNIFORM3IVPROC dolUniform3iv;
PFNDOLUNIFORM4FPROC dolUniform4f;
PFNDOLUNIFORM4FVPROC dolUniform4fv;
PFNDOLUNIFORM4IPROC dolUniform4i;
PFNDOLUNIFORM4IVPROC dolUniform4iv;
PFNDOLUNIFORMMATRIX2FVPROC dolUniformMatrix2fv;
PFNDOLUNIFORMMATRIX3FVPROC dolUniformMatrix3fv;
PFNDOLUNIFORMMATRIX4FVPROC dolUniformMatrix4fv;
PFNDOLUSEPROGRAMPROC dolUseProgram;
PFNDOLVALIDATEPROGRAMPROC dolValidateProgram;
PFNDOLVERTEXATTRIB1DPROC dolVertexAttrib1d;
PFNDOLVERTEXATTRIB1DVPROC dolVertexAttrib1dv;
PFNDOLVERTEXATTRIB1FPROC dolVertexAttrib1f;
PFNDOLVERTEXATTRIB1FVPROC dolVertexAttrib1fv;
PFNDOLVERTEXATTRIB1SPROC dolVertexAttrib1s;
PFNDOLVERTEXATTRIB1SVPROC dolVertexAttrib1sv;
PFNDOLVERTEXATTRIB2DPROC dolVertexAttrib2d;
PFNDOLVERTEXATTRIB2DVPROC dolVertexAttrib2dv;
PFNDOLVERTEXATTRIB2FPROC dolVertexAttrib2f;
PFNDOLVERTEXATTRIB2FVPROC dolVertexAttrib2fv;
PFNDOLVERTEXATTRIB2SPROC dolVertexAttrib2s;
PFNDOLVERTEXATTRIB2SVPROC dolVertexAttrib2sv;
PFNDOLVERTEXATTRIB3DPROC dolVertexAttrib3d;
PFNDOLVERTEXATTRIB3DVPROC dolVertexAttrib3dv;
PFNDOLVERTEXATTRIB3FPROC dolVertexAttrib3f;
PFNDOLVERTEXATTRIB3FVPROC dolVertexAttrib3fv;
PFNDOLVERTEXATTRIB3SPROC dolVertexAttrib3s;
PFNDOLVERTEXATTRIB3SVPROC dolVertexAttrib3sv;
PFNDOLVERTEXATTRIB4NBVPROC dolVertexAttrib4Nbv;
PFNDOLVERTEXATTRIB4NIVPROC dolVertexAttrib4Niv;
PFNDOLVERTEXATTRIB4NSVPROC dolVertexAttrib4Nsv;
PFNDOLVERTEXATTRIB4NUBPROC dolVertexAttrib4Nub;
PFNDOLVERTEXATTRIB4NUBVPROC dolVertexAttrib4Nubv;
PFNDOLVERTEXATTRIB4NUIVPROC dolVertexAttrib4Nuiv;
PFNDOLVERTEXATTRIB4NUSVPROC dolVertexAttrib4Nusv;
PFNDOLVERTEXATTRIB4BVPROC dolVertexAttrib4bv;
PFNDOLVERTEXATTRIB4DPROC dolVertexAttrib4d;
PFNDOLVERTEXATTRIB4DVPROC dolVertexAttrib4dv;
PFNDOLVERTEXATTRIB4FPROC dolVertexAttrib4f;
PFNDOLVERTEXATTRIB4FVPROC dolVertexAttrib4fv;
PFNDOLVERTEXATTRIB4IVPROC dolVertexAttrib4iv;
PFNDOLVERTEXATTRIB4SPROC dolVertexAttrib4s;
PFNDOLVERTEXATTRIB4SVPROC dolVertexAttrib4sv;
PFNDOLVERTEXATTRIB4UBVPROC dolVertexAttrib4ubv;
PFNDOLVERTEXATTRIB4UIVPROC dolVertexAttrib4uiv;
PFNDOLVERTEXATTRIB4USVPROC dolVertexAttrib4usv;
PFNDOLVERTEXATTRIBPOINTERPROC dolVertexAttribPointer;

// gl_2_1
PFNDOLUNIFORMMATRIX2X3FVPROC dolUniformMatrix2x3fv;
PFNDOLUNIFORMMATRIX2X4FVPROC dolUniformMatrix2x4fv;
PFNDOLUNIFORMMATRIX3X2FVPROC dolUniformMatrix3x2fv;
PFNDOLUNIFORMMATRIX3X4FVPROC dolUniformMatrix3x4fv;
PFNDOLUNIFORMMATRIX4X2FVPROC dolUniformMatrix4x2fv;
PFNDOLUNIFORMMATRIX4X3FVPROC dolUniformMatrix4x3fv;

// gl_3_0
PFNDOLBEGINCONDITIONALRENDERPROC dolBeginConditionalRender;
PFNDOLBEGINTRANSFORMFEEDBACKPROC dolBeginTransformFeedback;
PFNDOLBINDFRAGDATALOCATIONPROC dolBindFragDataLocation;
PFNDOLCLAMPCOLORPROC dolClampColor;
PFNDOLCLEARBUFFERFIPROC dolClearBufferfi;
PFNDOLCLEARBUFFERFVPROC dolClearBufferfv;
PFNDOLCLEARBUFFERIVPROC dolClearBufferiv;
PFNDOLCLEARBUFFERUIVPROC dolClearBufferuiv;
PFNDOLCOLORMASKIPROC dolColorMaski;
PFNDOLDISABLEIPROC dolDisablei;
PFNDOLENABLEIPROC dolEnablei;
PFNDOLENDCONDITIONALRENDERPROC dolEndConditionalRender;
PFNDOLENDTRANSFORMFEEDBACKPROC dolEndTransformFeedback;
PFNDOLGETBOOLEANI_VPROC dolGetBooleani_v;
PFNDOLGETFRAGDATALOCATIONPROC dolGetFragDataLocation;
PFNDOLGETSTRINGIPROC dolGetStringi;
PFNDOLGETTEXPARAMETERIIVPROC dolGetTexParameterIiv;
PFNDOLGETTEXPARAMETERIUIVPROC dolGetTexParameterIuiv;
PFNDOLGETTRANSFORMFEEDBACKVARYINGPROC dolGetTransformFeedbackVarying;
PFNDOLGETUNIFORMUIVPROC dolGetUniformuiv;
PFNDOLGETVERTEXATTRIBIIVPROC dolGetVertexAttribIiv;
PFNDOLGETVERTEXATTRIBIUIVPROC dolGetVertexAttribIuiv;
PFNDOLISENABLEDIPROC dolIsEnabledi;
PFNDOLTEXPARAMETERIIVPROC dolTexParameterIiv;
PFNDOLTEXPARAMETERIUIVPROC dolTexParameterIuiv;
PFNDOLTRANSFORMFEEDBACKVARYINGSPROC dolTransformFeedbackVaryings;
PFNDOLUNIFORM1UIPROC dolUniform1ui;
PFNDOLUNIFORM1UIVPROC dolUniform1uiv;
PFNDOLUNIFORM2UIPROC dolUniform2ui;
PFNDOLUNIFORM2UIVPROC dolUniform2uiv;
PFNDOLUNIFORM3UIPROC dolUniform3ui;
PFNDOLUNIFORM3UIVPROC dolUniform3uiv;
PFNDOLUNIFORM4UIPROC dolUniform4ui;
PFNDOLUNIFORM4UIVPROC dolUniform4uiv;
PFNDOLVERTEXATTRIBI1IPROC dolVertexAttribI1i;
PFNDOLVERTEXATTRIBI1IVPROC dolVertexAttribI1iv;
PFNDOLVERTEXATTRIBI1UIPROC dolVertexAttribI1ui;
PFNDOLVERTEXATTRIBI1UIVPROC dolVertexAttribI1uiv;
PFNDOLVERTEXATTRIBI2IPROC dolVertexAttribI2i;
PFNDOLVERTEXATTRIBI2IVPROC dolVertexAttribI2iv;
PFNDOLVERTEXATTRIBI2UIPROC dolVertexAttribI2ui;
PFNDOLVERTEXATTRIBI2UIVPROC dolVertexAttribI2uiv;
PFNDOLVERTEXATTRIBI3IPROC dolVertexAttribI3i;
PFNDOLVERTEXATTRIBI3IVPROC dolVertexAttribI3iv;
PFNDOLVERTEXATTRIBI3UIPROC dolVertexAttribI3ui;
PFNDOLVERTEXATTRIBI3UIVPROC dolVertexAttribI3uiv;
PFNDOLVERTEXATTRIBI4BVPROC dolVertexAttribI4bv;
PFNDOLVERTEXATTRIBI4IPROC dolVertexAttribI4i;
PFNDOLVERTEXATTRIBI4IVPROC dolVertexAttribI4iv;
PFNDOLVERTEXATTRIBI4SVPROC dolVertexAttribI4sv;
PFNDOLVERTEXATTRIBI4UBVPROC dolVertexAttribI4ubv;
PFNDOLVERTEXATTRIBI4UIPROC dolVertexAttribI4ui;
PFNDOLVERTEXATTRIBI4UIVPROC dolVertexAttribI4uiv;
PFNDOLVERTEXATTRIBI4USVPROC dolVertexAttribI4usv;
PFNDOLVERTEXATTRIBIPOINTERPROC dolVertexAttribIPointer;

// gl_3_1
PFNDOLDRAWARRAYSINSTANCEDPROC dolDrawArraysInstanced;
PFNDOLDRAWELEMENTSINSTANCEDPROC dolDrawElementsInstanced;
PFNDOLPRIMITIVERESTARTINDEXPROC dolPrimitiveRestartIndex;
PFNDOLTEXBUFFERPROC dolTexBuffer;

// gl_3_2
PFNDOLFRAMEBUFFERTEXTUREPROC dolFramebufferTexture;
PFNDOLGETBUFFERPARAMETERI64VPROC dolGetBufferParameteri64v;
PFNDOLGETINTEGER64I_VPROC dolGetInteger64i_v;

// gl 4_2
PFNDOLDRAWARRAYSINSTANCEDBASEINSTANCEPROC dolDrawArraysInstancedBaseInstance;
PFNDOLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC dolDrawElementsInstancedBaseInstance;
PFNDOLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC dolDrawElementsInstancedBaseVertexBaseInstance;
PFNDOLGETINTERNALFORMATIVPROC dolGetInternalformativ;
PFNDOLGETACTIVEATOMICCOUNTERBUFFERIVPROC dolGetActiveAtomicCounterBufferiv;
PFNDOLBINDIMAGETEXTUREPROC dolBindImageTexture;
PFNDOLMEMORYBARRIERPROC dolMemoryBarrier;
PFNDOLTEXSTORAGE1DPROC dolTexStorage1D;
PFNDOLTEXSTORAGE2DPROC dolTexStorage2D;
PFNDOLTEXSTORAGE3DPROC dolTexStorage3D;
PFNDOLDRAWTRANSFORMFEEDBACKINSTANCEDPROC dolDrawTransformFeedbackInstanced;
PFNDOLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC dolDrawTransformFeedbackStreamInstanced;

// gl_4_3
PFNDOLCLEARBUFFERDATAPROC dolClearBufferData;
PFNDOLCLEARBUFFERSUBDATAPROC dolClearBufferSubData;
PFNDOLDISPATCHCOMPUTEPROC dolDispatchCompute;
PFNDOLDISPATCHCOMPUTEINDIRECTPROC dolDispatchComputeIndirect;
PFNDOLFRAMEBUFFERPARAMETERIPROC dolFramebufferParameteri;
PFNDOLGETFRAMEBUFFERPARAMETERIVPROC dolGetFramebufferParameteriv;
PFNDOLGETINTERNALFORMATI64VPROC dolGetInternalformati64v;
PFNDOLINVALIDATETEXSUBIMAGEPROC dolInvalidateTexSubImage;
PFNDOLINVALIDATETEXIMAGEPROC dolInvalidateTexImage;
PFNDOLINVALIDATEBUFFERSUBDATAPROC dolInvalidateBufferSubData;
PFNDOLINVALIDATEBUFFERDATAPROC dolInvalidateBufferData;
PFNDOLINVALIDATEFRAMEBUFFERPROC dolInvalidateFramebuffer;
PFNDOLINVALIDATESUBFRAMEBUFFERPROC dolInvalidateSubFramebuffer;
PFNDOLMULTIDRAWARRAYSINDIRECTPROC dolMultiDrawArraysIndirect;
PFNDOLMULTIDRAWELEMENTSINDIRECTPROC dolMultiDrawElementsIndirect;
PFNDOLGETPROGRAMINTERFACEIVPROC dolGetProgramInterfaceiv;
PFNDOLGETPROGRAMRESOURCEINDEXPROC dolGetProgramResourceIndex;
PFNDOLGETPROGRAMRESOURCENAMEPROC dolGetProgramResourceName;
PFNDOLGETPROGRAMRESOURCEIVPROC dolGetProgramResourceiv;
PFNDOLGETPROGRAMRESOURCELOCATIONPROC dolGetProgramResourceLocation;
PFNDOLGETPROGRAMRESOURCELOCATIONINDEXPROC dolGetProgramResourceLocationIndex;
PFNDOLTEXBUFFERRANGEPROC dolTexBufferRange;
PFNDOLTEXTUREVIEWPROC dolTextureView;
PFNDOLBINDVERTEXBUFFERPROC dolBindVertexBuffer;
PFNDOLVERTEXATTRIBFORMATPROC dolVertexAttribFormat;
PFNDOLVERTEXATTRIBIFORMATPROC dolVertexAttribIFormat;
PFNDOLVERTEXATTRIBLFORMATPROC dolVertexAttribLFormat;
PFNDOLVERTEXATTRIBBINDINGPROC dolVertexAttribBinding;
PFNDOLVERTEXBINDINGDIVISORPROC dolVertexBindingDivisor;

// gl_4_4
PFNDOLCLEARTEXIMAGEPROC dolClearTexImage;
PFNDOLCLEARTEXSUBIMAGEPROC dolClearTexSubImage;
PFNDOLBINDBUFFERSBASEPROC dolBindBuffersBase;
PFNDOLBINDBUFFERSRANGEPROC dolBindBuffersRange;
PFNDOLBINDTEXTURESPROC dolBindTextures;
PFNDOLBINDSAMPLERSPROC dolBindSamplers;
PFNDOLBINDIMAGETEXTURESPROC dolBindImageTextures;
PFNDOLBINDVERTEXBUFFERSPROC dolBindVertexBuffers;

// gl_4_5
PFNDOLCREATETRANSFORMFEEDBACKSPROC dolCreateTransformFeedbacks;
PFNDOLTRANSFORMFEEDBACKBUFFERBASEPROC dolTransformFeedbackBufferBase;
PFNDOLTRANSFORMFEEDBACKBUFFERRANGEPROC dolTransformFeedbackBufferRange;
PFNDOLGETTRANSFORMFEEDBACKIVPROC dolGetTransformFeedbackiv;
PFNDOLGETTRANSFORMFEEDBACKI_VPROC dolGetTransformFeedbacki_v;
PFNDOLGETTRANSFORMFEEDBACKI64_VPROC dolGetTransformFeedbacki64_v;
PFNDOLCREATEBUFFERSPROC dolCreateBuffers;
PFNDOLNAMEDBUFFERSTORAGEPROC dolNamedBufferStorage;
PFNDOLNAMEDBUFFERDATAPROC dolNamedBufferData;
PFNDOLNAMEDBUFFERSUBDATAPROC dolNamedBufferSubData;
PFNDOLCOPYNAMEDBUFFERSUBDATAPROC dolCopyNamedBufferSubData;
PFNDOLCLEARNAMEDBUFFERDATAPROC dolClearNamedBufferData;
PFNDOLCLEARNAMEDBUFFERSUBDATAPROC dolClearNamedBufferSubData;
PFNDOLMAPNAMEDBUFFERPROC dolMapNamedBuffer;
PFNDOLMAPNAMEDBUFFERRANGEPROC dolMapNamedBufferRange;
PFNDOLUNMAPNAMEDBUFFERPROC dolUnmapNamedBuffer;
PFNDOLFLUSHMAPPEDNAMEDBUFFERRANGEPROC dolFlushMappedNamedBufferRange;
PFNDOLGETNAMEDBUFFERPARAMETERIVPROC dolGetNamedBufferParameteriv;
PFNDOLGETNAMEDBUFFERPARAMETERI64VPROC dolGetNamedBufferParameteri64v;
PFNDOLGETNAMEDBUFFERPOINTERVPROC dolGetNamedBufferPointerv;
PFNDOLGETNAMEDBUFFERSUBDATAPROC dolGetNamedBufferSubData;
PFNDOLCREATEFRAMEBUFFERSPROC dolCreateFramebuffers;
PFNDOLNAMEDFRAMEBUFFERRENDERBUFFERPROC dolNamedFramebufferRenderbuffer;
PFNDOLNAMEDFRAMEBUFFERPARAMETERIPROC dolNamedFramebufferParameteri;
PFNDOLNAMEDFRAMEBUFFERTEXTUREPROC dolNamedFramebufferTexture;
PFNDOLNAMEDFRAMEBUFFERTEXTURELAYERPROC dolNamedFramebufferTextureLayer;
PFNDOLNAMEDFRAMEBUFFERDRAWBUFFERPROC dolNamedFramebufferDrawBuffer;
PFNDOLNAMEDFRAMEBUFFERDRAWBUFFERSPROC dolNamedFramebufferDrawBuffers;
PFNDOLNAMEDFRAMEBUFFERREADBUFFERPROC dolNamedFramebufferReadBuffer;
PFNDOLINVALIDATENAMEDFRAMEBUFFERDATAPROC dolInvalidateNamedFramebufferData;
PFNDOLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC dolInvalidateNamedFramebufferSubData;
PFNDOLCLEARNAMEDFRAMEBUFFERIVPROC dolClearNamedFramebufferiv;
PFNDOLCLEARNAMEDFRAMEBUFFERUIVPROC dolClearNamedFramebufferuiv;
PFNDOLCLEARNAMEDFRAMEBUFFERFVPROC dolClearNamedFramebufferfv;
PFNDOLCLEARNAMEDFRAMEBUFFERFIPROC dolClearNamedFramebufferfi;
PFNDOLBLITNAMEDFRAMEBUFFERPROC dolBlitNamedFramebuffer;
PFNDOLCHECKNAMEDFRAMEBUFFERSTATUSPROC dolCheckNamedFramebufferStatus;
PFNDOLGETNAMEDFRAMEBUFFERPARAMETERIVPROC dolGetNamedFramebufferParameteriv;
PFNDOLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC dolGetNamedFramebufferAttachmentParameteriv;
PFNDOLCREATERENDERBUFFERSPROC dolCreateRenderbuffers;
PFNDOLNAMEDRENDERBUFFERSTORAGEPROC dolNamedRenderbufferStorage;
PFNDOLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC dolNamedRenderbufferStorageMultisample;
PFNDOLGETNAMEDRENDERBUFFERPARAMETERIVPROC dolGetNamedRenderbufferParameteriv;
PFNDOLCREATETEXTURESPROC dolCreateTextures;
PFNDOLTEXTUREBUFFERPROC dolTextureBuffer;
PFNDOLTEXTUREBUFFERRANGEPROC dolTextureBufferRange;
PFNDOLTEXTURESTORAGE1DPROC dolTextureStorage1D;
PFNDOLTEXTURESTORAGE2DPROC dolTextureStorage2D;
PFNDOLTEXTURESTORAGE3DPROC dolTextureStorage3D;
PFNDOLTEXTURESTORAGE2DMULTISAMPLEPROC dolTextureStorage2DMultisample;
PFNDOLTEXTURESTORAGE3DMULTISAMPLEPROC dolTextureStorage3DMultisample;
PFNDOLTEXTURESUBIMAGE1DPROC dolTextureSubImage1D;
PFNDOLTEXTURESUBIMAGE2DPROC dolTextureSubImage2D;
PFNDOLTEXTURESUBIMAGE3DPROC dolTextureSubImage3D;
PFNDOLCOMPRESSEDTEXTURESUBIMAGE1DPROC dolCompressedTextureSubImage1D;
PFNDOLCOMPRESSEDTEXTURESUBIMAGE2DPROC dolCompressedTextureSubImage2D;
PFNDOLCOMPRESSEDTEXTURESUBIMAGE3DPROC dolCompressedTextureSubImage3D;
PFNDOLCOPYTEXTURESUBIMAGE1DPROC dolCopyTextureSubImage1D;
PFNDOLCOPYTEXTURESUBIMAGE2DPROC dolCopyTextureSubImage2D;
PFNDOLCOPYTEXTURESUBIMAGE3DPROC dolCopyTextureSubImage3D;
PFNDOLTEXTUREPARAMETERFPROC dolTextureParameterf;
PFNDOLTEXTUREPARAMETERFVPROC dolTextureParameterfv;
PFNDOLTEXTUREPARAMETERIPROC dolTextureParameteri;
PFNDOLTEXTUREPARAMETERIIVPROC dolTextureParameterIiv;
PFNDOLTEXTUREPARAMETERIUIVPROC dolTextureParameterIuiv;
PFNDOLTEXTUREPARAMETERIVPROC dolTextureParameteriv;
PFNDOLGENERATETEXTUREMIPMAPPROC dolGenerateTextureMipmap;
PFNDOLBINDTEXTUREUNITPROC dolBindTextureUnit;
PFNDOLGETTEXTUREIMAGEPROC dolGetTextureImage;
PFNDOLGETCOMPRESSEDTEXTUREIMAGEPROC dolGetCompressedTextureImage;
PFNDOLGETTEXTURELEVELPARAMETERFVPROC dolGetTextureLevelParameterfv;
PFNDOLGETTEXTURELEVELPARAMETERIVPROC dolGetTextureLevelParameteriv;
PFNDOLGETTEXTUREPARAMETERFVPROC dolGetTextureParameterfv;
PFNDOLGETTEXTUREPARAMETERIIVPROC dolGetTextureParameterIiv;
PFNDOLGETTEXTUREPARAMETERIUIVPROC dolGetTextureParameterIuiv;
PFNDOLGETTEXTUREPARAMETERIVPROC dolGetTextureParameteriv;
PFNDOLCREATEVERTEXARRAYSPROC dolCreateVertexArrays;
PFNDOLDISABLEVERTEXARRAYATTRIBPROC dolDisableVertexArrayAttrib;
PFNDOLENABLEVERTEXARRAYATTRIBPROC dolEnableVertexArrayAttrib;
PFNDOLVERTEXARRAYELEMENTBUFFERPROC dolVertexArrayElementBuffer;
PFNDOLVERTEXARRAYVERTEXBUFFERPROC dolVertexArrayVertexBuffer;
PFNDOLVERTEXARRAYVERTEXBUFFERSPROC dolVertexArrayVertexBuffers;
PFNDOLVERTEXARRAYATTRIBBINDINGPROC dolVertexArrayAttribBinding;
PFNDOLVERTEXARRAYATTRIBFORMATPROC dolVertexArrayAttribFormat;
PFNDOLVERTEXARRAYATTRIBIFORMATPROC dolVertexArrayAttribIFormat;
PFNDOLVERTEXARRAYATTRIBLFORMATPROC dolVertexArrayAttribLFormat;
PFNDOLVERTEXARRAYBINDINGDIVISORPROC dolVertexArrayBindingDivisor;
PFNDOLGETVERTEXARRAYIVPROC dolGetVertexArrayiv;
PFNDOLGETVERTEXARRAYINDEXEDIVPROC dolGetVertexArrayIndexediv;
PFNDOLGETVERTEXARRAYINDEXED64IVPROC dolGetVertexArrayIndexed64iv;
PFNDOLCREATESAMPLERSPROC dolCreateSamplers;
PFNDOLCREATEPROGRAMPIPELINESPROC dolCreateProgramPipelines;
PFNDOLCREATEQUERIESPROC dolCreateQueries;
PFNDOLGETQUERYBUFFEROBJECTI64VPROC dolGetQueryBufferObjecti64v;
PFNDOLGETQUERYBUFFEROBJECTIVPROC dolGetQueryBufferObjectiv;
PFNDOLGETQUERYBUFFEROBJECTUI64VPROC dolGetQueryBufferObjectui64v;
PFNDOLGETQUERYBUFFEROBJECTUIVPROC dolGetQueryBufferObjectuiv;
PFNDOLMEMORYBARRIERBYREGIONPROC dolMemoryBarrierByRegion;
PFNDOLGETTEXTURESUBIMAGEPROC dolGetTextureSubImage;
PFNDOLGETCOMPRESSEDTEXTURESUBIMAGEPROC dolGetCompressedTextureSubImage;
PFNDOLGETGRAPHICSRESETSTATUSPROC dolGetGraphicsResetStatus;
PFNDOLGETNCOMPRESSEDTEXIMAGEPROC dolGetnCompressedTexImage;
PFNDOLGETNTEXIMAGEPROC dolGetnTexImage;
PFNDOLGETNUNIFORMDVPROC dolGetnUniformdv;
PFNDOLGETNUNIFORMFVPROC dolGetnUniformfv;
PFNDOLGETNUNIFORMIVPROC dolGetnUniformiv;
PFNDOLGETNUNIFORMUIVPROC dolGetnUniformuiv;
PFNDOLREADNPIXELSPROC dolReadnPixels;
PFNDOLGETNMAPDVPROC dolGetnMapdv;
PFNDOLGETNMAPFVPROC dolGetnMapfv;
PFNDOLGETNMAPIVPROC dolGetnMapiv;
PFNDOLGETNPIXELMAPFVPROC dolGetnPixelMapfv;
PFNDOLGETNPIXELMAPUIVPROC dolGetnPixelMapuiv;
PFNDOLGETNPIXELMAPUSVPROC dolGetnPixelMapusv;
PFNDOLGETNPOLYGONSTIPPLEPROC dolGetnPolygonStipple;
PFNDOLGETNCOLORTABLEPROC dolGetnColorTable;
PFNDOLGETNCONVOLUTIONFILTERPROC dolGetnConvolutionFilter;
PFNDOLGETNSEPARABLEFILTERPROC dolGetnSeparableFilter;
PFNDOLGETNHISTOGRAMPROC dolGetnHistogram;
PFNDOLGETNMINMAXPROC dolGetnMinmax;
PFNDOLTEXTUREBARRIERPROC dolTextureBarrier;

// ARB_uniform_buffer_object
PFNDOLBINDBUFFERBASEPROC dolBindBufferBase;
PFNDOLBINDBUFFERRANGEPROC dolBindBufferRange;
PFNDOLGETACTIVEUNIFORMBLOCKNAMEPROC dolGetActiveUniformBlockName;
PFNDOLGETACTIVEUNIFORMBLOCKIVPROC dolGetActiveUniformBlockiv;
PFNDOLGETACTIVEUNIFORMNAMEPROC dolGetActiveUniformName;
PFNDOLGETACTIVEUNIFORMSIVPROC dolGetActiveUniformsiv;
PFNDOLGETINTEGERI_VPROC dolGetIntegeri_v;
PFNDOLGETUNIFORMBLOCKINDEXPROC dolGetUniformBlockIndex;
PFNDOLGETUNIFORMINDICESPROC dolGetUniformIndices;
PFNDOLUNIFORMBLOCKBINDINGPROC dolUniformBlockBinding;

// ARB_sampler_objects
PFNDOLBINDSAMPLERPROC dolBindSampler;
PFNDOLDELETESAMPLERSPROC dolDeleteSamplers;
PFNDOLGENSAMPLERSPROC dolGenSamplers;
PFNDOLGETSAMPLERPARAMETERIIVPROC dolGetSamplerParameterIiv;
PFNDOLGETSAMPLERPARAMETERIUIVPROC dolGetSamplerParameterIuiv;
PFNDOLGETSAMPLERPARAMETERFVPROC dolGetSamplerParameterfv;
PFNDOLGETSAMPLERPARAMETERIVPROC dolGetSamplerParameteriv;
PFNDOLISSAMPLERPROC dolIsSampler;
PFNDOLSAMPLERPARAMETERIIVPROC dolSamplerParameterIiv;
PFNDOLSAMPLERPARAMETERIUIVPROC dolSamplerParameterIuiv;
PFNDOLSAMPLERPARAMETERFPROC dolSamplerParameterf;
PFNDOLSAMPLERPARAMETERFVPROC dolSamplerParameterfv;
PFNDOLSAMPLERPARAMETERIPROC dolSamplerParameteri;
PFNDOLSAMPLERPARAMETERIVPROC dolSamplerParameteriv;

// ARB_map_buffer_range
PFNDOLFLUSHMAPPEDBUFFERRANGEPROC dolFlushMappedBufferRange;
PFNDOLMAPBUFFERRANGEPROC dolMapBufferRange;

// ARB_vertex_array_object
PFNDOLBINDVERTEXARRAYPROC dolBindVertexArray;
PFNDOLDELETEVERTEXARRAYSPROC dolDeleteVertexArrays;
PFNDOLGENVERTEXARRAYSPROC dolGenVertexArrays;
PFNDOLISVERTEXARRAYPROC dolIsVertexArray;

// ARB_framebuffer_object
PFNDOLBINDFRAMEBUFFERPROC dolBindFramebuffer;
PFNDOLBINDRENDERBUFFERPROC dolBindRenderbuffer;
PFNDOLBLITFRAMEBUFFERPROC dolBlitFramebuffer;
PFNDOLCHECKFRAMEBUFFERSTATUSPROC dolCheckFramebufferStatus;
PFNDOLDELETEFRAMEBUFFERSPROC dolDeleteFramebuffers;
PFNDOLDELETERENDERBUFFERSPROC dolDeleteRenderbuffers;
PFNDOLFRAMEBUFFERRENDERBUFFERPROC dolFramebufferRenderbuffer;
PFNDOLFRAMEBUFFERTEXTURE1DPROC dolFramebufferTexture1D;
PFNDOLFRAMEBUFFERTEXTURE2DPROC dolFramebufferTexture2D;
PFNDOLFRAMEBUFFERTEXTURE3DPROC dolFramebufferTexture3D;
PFNDOLFRAMEBUFFERTEXTURELAYERPROC dolFramebufferTextureLayer;
PFNDOLGENFRAMEBUFFERSPROC dolGenFramebuffers;
PFNDOLGENRENDERBUFFERSPROC dolGenRenderbuffers;
PFNDOLGENERATEMIPMAPPROC dolGenerateMipmap;
PFNDOLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC dolGetFramebufferAttachmentParameteriv;
PFNDOLGETRENDERBUFFERPARAMETERIVPROC dolGetRenderbufferParameteriv;
PFNDOLISFRAMEBUFFERPROC dolIsFramebuffer;
PFNDOLISRENDERBUFFERPROC dolIsRenderbuffer;
PFNDOLRENDERBUFFERSTORAGEPROC dolRenderbufferStorage;
PFNDOLRENDERBUFFERSTORAGEMULTISAMPLEPROC dolRenderbufferStorageMultisample;

// ARB_get_program_binary
PFNDOLGETPROGRAMBINARYPROC dolGetProgramBinary;
PFNDOLPROGRAMBINARYPROC dolProgramBinary;
PFNDOLPROGRAMPARAMETERIPROC dolProgramParameteri;

// ARB_sync
PFNDOLCLIENTWAITSYNCPROC dolClientWaitSync;
PFNDOLDELETESYNCPROC dolDeleteSync;
PFNDOLFENCESYNCPROC dolFenceSync;
PFNDOLGETINTEGER64VPROC dolGetInteger64v;
PFNDOLGETSYNCIVPROC dolGetSynciv;
PFNDOLISSYNCPROC dolIsSync;
PFNDOLWAITSYNCPROC dolWaitSync;

// ARB_texture_multisample
PFNDOLTEXIMAGE2DMULTISAMPLEPROC dolTexImage2DMultisample;
PFNDOLTEXIMAGE3DMULTISAMPLEPROC dolTexImage3DMultisample;
PFNDOLGETMULTISAMPLEFVPROC dolGetMultisamplefv;
PFNDOLSAMPLEMASKIPROC dolSampleMaski;

// ARB_texture_storage_multisample
PFNDOLTEXSTORAGE2DMULTISAMPLEPROC dolTexStorage2DMultisample;
PFNDOLTEXSTORAGE3DMULTISAMPLEPROC dolTexStorage3DMultisample;

// ARB_ES2_compatibility
PFNDOLCLEARDEPTHFPROC dolClearDepthf;
PFNDOLDEPTHRANGEFPROC dolDepthRangef;
PFNDOLGETSHADERPRECISIONFORMATPROC dolGetShaderPrecisionFormat;
PFNDOLRELEASESHADERCOMPILERPROC dolReleaseShaderCompiler;
PFNDOLSHADERBINARYPROC dolShaderBinary;

// NV_primitive_restart
PFNDOLPRIMITIVERESTARTINDEXNVPROC dolPrimitiveRestartIndexNV;
PFNDOLPRIMITIVERESTARTNVPROC dolPrimitiveRestartNV;

// ARB_blend_func_extended
PFNDOLBINDFRAGDATALOCATIONINDEXEDPROC dolBindFragDataLocationIndexed;
PFNDOLGETFRAGDATAINDEXPROC dolGetFragDataIndex;

// ARB_viewport_array
PFNDOLDEPTHRANGEARRAYVPROC dolDepthRangeArrayv;
PFNDOLDEPTHRANGEINDEXEDPROC dolDepthRangeIndexed;
PFNDOLGETDOUBLEI_VPROC dolGetDoublei_v;
PFNDOLGETFLOATI_VPROC dolGetFloati_v;
PFNDOLSCISSORARRAYVPROC dolScissorArrayv;
PFNDOLSCISSORINDEXEDPROC dolScissorIndexed;
PFNDOLSCISSORINDEXEDVPROC dolScissorIndexedv;
PFNDOLVIEWPORTARRAYVPROC dolViewportArrayv;
PFNDOLVIEWPORTINDEXEDFPROC dolViewportIndexedf;
PFNDOLVIEWPORTINDEXEDFVPROC dolViewportIndexedfv;

// ARB_draw_elements_base_vertex
PFNDOLDRAWELEMENTSBASEVERTEXPROC dolDrawElementsBaseVertex;
PFNDOLDRAWELEMENTSINSTANCEDBASEVERTEXPROC dolDrawElementsInstancedBaseVertex;
PFNDOLDRAWRANGEELEMENTSBASEVERTEXPROC dolDrawRangeElementsBaseVertex;
PFNDOLMULTIDRAWELEMENTSBASEVERTEXPROC dolMultiDrawElementsBaseVertex;

// ARB_sample_shading
PFNDOLMINSAMPLESHADINGARBPROC dolMinSampleShading;

// ARB_debug_output
PFNDOLDEBUGMESSAGECALLBACKARBPROC dolDebugMessageCallbackARB;
PFNDOLDEBUGMESSAGECONTROLARBPROC dolDebugMessageControlARB;
PFNDOLDEBUGMESSAGEINSERTARBPROC dolDebugMessageInsertARB;
PFNDOLGETDEBUGMESSAGELOGARBPROC dolGetDebugMessageLogARB;

// KHR_debug
PFNDOLDEBUGMESSAGECALLBACKPROC dolDebugMessageCallback;
PFNDOLDEBUGMESSAGECONTROLPROC dolDebugMessageControl;
PFNDOLDEBUGMESSAGEINSERTPROC dolDebugMessageInsert;
PFNDOLGETDEBUGMESSAGELOGPROC dolGetDebugMessageLog;
PFNDOLGETOBJECTLABELPROC dolGetObjectLabel;
PFNDOLGETOBJECTPTRLABELPROC dolGetObjectPtrLabel;
PFNDOLOBJECTLABELPROC dolObjectLabel;
PFNDOLOBJECTPTRLABELPROC dolObjectPtrLabel;
PFNDOLPOPDEBUGGROUPPROC dolPopDebugGroup;
PFNDOLPUSHDEBUGGROUPPROC dolPushDebugGroup;

// ARB_buffer_storage
PFNDOLBUFFERSTORAGEPROC dolBufferStorage;

// GL_NV_occlusion_query_samples
PFNDOLGENOCCLUSIONQUERIESNVPROC dolGenOcclusionQueriesNV;
PFNDOLDELETEOCCLUSIONQUERIESNVPROC dolDeleteOcclusionQueriesNV;
PFNDOLISOCCLUSIONQUERYNVPROC dolIsOcclusionQueryNV;
PFNDOLBEGINOCCLUSIONQUERYNVPROC dolBeginOcclusionQueryNV;
PFNDOLENDOCCLUSIONQUERYNVPROC dolEndOcclusionQueryNV;
PFNDOLGETOCCLUSIONQUERYIVNVPROC dolGetOcclusionQueryivNV;
PFNDOLGETOCCLUSIONQUERYUIVNVPROC dolGetOcclusionQueryuivNV;

// ARB_clip_control
PFNDOLCLIPCONTROLPROC dolClipControl;

// ARB_copy_image
PFNDOLCOPYIMAGESUBDATAPROC dolCopyImageSubData;

// ARB_shader_storage_buffer_object
PFNDOLSHADERSTORAGEBLOCKBINDINGPROC dolShaderStorageBlockBinding;

// Creates a GLFunc object that requires a feature
#define GLFUNC_REQUIRES(x, y) { (void**)&x, #x, y }
// Creates a GLFunc object with a different function suffix
// For when we want to use the same function pointer, but different function name
#define GLFUNC_SUFFIX(x, y, z) { (void**)&x, #x #y, z }
// Creates a GLFunc object that should always be able to get grabbed
// Used for Desktop OpenGL functions that should /always/ be provided.
// aka GL 1.1/1.2/1.3/1.4
#define GLFUNC_ALWAYS_REQUIRED(x) { (void**)&x, #x, "VERSION_GL" }
// Creates a GLFunc object that should be able to get grabbed
// on both GL and ES
#define GL_ES_FUNC_ALWAYS_REQUIRED(x) { (void**)&x, #x, "VERSION_GL |VERSION_GLES_2" }
// Creates a GLFunc object that should be able to get grabbed
// on both GL and ES 3.0
#define GL_ES3_FUNC_ALWAYS_REQUIRED(x) { (void**)&x, #x, "VERSION_GL |VERSION_GLES_3" }
// Creates a GLFunc object that should be able to get grabbed
// on both GL and ES 3.2
#define GL_ES32_FUNC_ALWAYS_REQUIRED(x) { (void**)&x, #x, "VERSION_GL |VERSION_GLES_3_2" }

struct GLFunc
{
	void** function_ptr;
	const std::string function_name;
	const std::string requirements;
};

const GLFunc gl_function_array[] =
{
	// gl_1_1
	GLFUNC_ALWAYS_REQUIRED(glClearIndex),
	GLFUNC_ALWAYS_REQUIRED(glIndexMask),
	GLFUNC_ALWAYS_REQUIRED(glAlphaFunc),
	GLFUNC_ALWAYS_REQUIRED(glLogicOp),
	GLFUNC_ALWAYS_REQUIRED(glPointSize),
	GLFUNC_ALWAYS_REQUIRED(glLineStipple),
	GLFUNC_ALWAYS_REQUIRED(glPolygonMode),
	GLFUNC_ALWAYS_REQUIRED(glPolygonStipple),
	GLFUNC_ALWAYS_REQUIRED(glGetPolygonStipple),
	GLFUNC_ALWAYS_REQUIRED(glEdgeFlag),
	GLFUNC_ALWAYS_REQUIRED(glEdgeFlagv),
	GLFUNC_ALWAYS_REQUIRED(glClipPlane),
	GLFUNC_ALWAYS_REQUIRED(glGetClipPlane),
	GLFUNC_ALWAYS_REQUIRED(glDrawBuffer),
	GLFUNC_ALWAYS_REQUIRED(glEnableClientState),
	GLFUNC_ALWAYS_REQUIRED(glDisableClientState),
	GLFUNC_ALWAYS_REQUIRED(glGetDoublev),
	GLFUNC_ALWAYS_REQUIRED(glPushAttrib),
	GLFUNC_ALWAYS_REQUIRED(glPopAttrib),
	GLFUNC_ALWAYS_REQUIRED(glPushClientAttrib),
	GLFUNC_ALWAYS_REQUIRED(glPopClientAttrib),
	GLFUNC_ALWAYS_REQUIRED(glRenderMode),
	GLFUNC_ALWAYS_REQUIRED(glClearDepth),
	GLFUNC_ALWAYS_REQUIRED(glDepthRange),
	GLFUNC_ALWAYS_REQUIRED(glClearAccum),
	GLFUNC_ALWAYS_REQUIRED(glAccum),
	GLFUNC_ALWAYS_REQUIRED(glMatrixMode),
	GLFUNC_ALWAYS_REQUIRED(glOrtho),
	GLFUNC_ALWAYS_REQUIRED(glFrustum),
	GLFUNC_ALWAYS_REQUIRED(glPushMatrix),
	GLFUNC_ALWAYS_REQUIRED(glPopMatrix),
	GLFUNC_ALWAYS_REQUIRED(glLoadIdentity),
	GLFUNC_ALWAYS_REQUIRED(glLoadMatrixd),
	GLFUNC_ALWAYS_REQUIRED(glLoadMatrixf),
	GLFUNC_ALWAYS_REQUIRED(glMultMatrixd),
	GLFUNC_ALWAYS_REQUIRED(glMultMatrixf),
	GLFUNC_ALWAYS_REQUIRED(glRotated),
	GLFUNC_ALWAYS_REQUIRED(glRotatef),
	GLFUNC_ALWAYS_REQUIRED(glScaled),
	GLFUNC_ALWAYS_REQUIRED(glScalef),
	GLFUNC_ALWAYS_REQUIRED(glTranslated),
	GLFUNC_ALWAYS_REQUIRED(glTranslatef),
	GLFUNC_ALWAYS_REQUIRED(glIsList),
	GLFUNC_ALWAYS_REQUIRED(glDeleteLists),
	GLFUNC_ALWAYS_REQUIRED(glGenLists),
	GLFUNC_ALWAYS_REQUIRED(glNewList),
	GLFUNC_ALWAYS_REQUIRED(glEndList),
	GLFUNC_ALWAYS_REQUIRED(glCallList),
	GLFUNC_ALWAYS_REQUIRED(glCallLists),
	GLFUNC_ALWAYS_REQUIRED(glListBase),
	GLFUNC_ALWAYS_REQUIRED(glBegin),
	GLFUNC_ALWAYS_REQUIRED(glEnd),
	GLFUNC_ALWAYS_REQUIRED(glVertex2d),
	GLFUNC_ALWAYS_REQUIRED(glVertex2f),
	GLFUNC_ALWAYS_REQUIRED(glVertex2i),
	GLFUNC_ALWAYS_REQUIRED(glVertex2s),
	GLFUNC_ALWAYS_REQUIRED(glVertex3d),
	GLFUNC_ALWAYS_REQUIRED(glVertex3f),
	GLFUNC_ALWAYS_REQUIRED(glVertex3i),
	GLFUNC_ALWAYS_REQUIRED(glVertex3s),
	GLFUNC_ALWAYS_REQUIRED(glVertex4d),
	GLFUNC_ALWAYS_REQUIRED(glVertex4f),
	GLFUNC_ALWAYS_REQUIRED(glVertex4i),
	GLFUNC_ALWAYS_REQUIRED(glVertex4s),
	GLFUNC_ALWAYS_REQUIRED(glVertex2dv),
	GLFUNC_ALWAYS_REQUIRED(glVertex2fv),
	GLFUNC_ALWAYS_REQUIRED(glVertex2iv),
	GLFUNC_ALWAYS_REQUIRED(glVertex2sv),
	GLFUNC_ALWAYS_REQUIRED(glVertex3dv),
	GLFUNC_ALWAYS_REQUIRED(glVertex3fv),
	GLFUNC_ALWAYS_REQUIRED(glVertex3iv),
	GLFUNC_ALWAYS_REQUIRED(glVertex3sv),
	GLFUNC_ALWAYS_REQUIRED(glVertex4dv),
	GLFUNC_ALWAYS_REQUIRED(glVertex4fv),
	GLFUNC_ALWAYS_REQUIRED(glVertex4iv),
	GLFUNC_ALWAYS_REQUIRED(glVertex4sv),
	GLFUNC_ALWAYS_REQUIRED(glNormal3b),
	GLFUNC_ALWAYS_REQUIRED(glNormal3d),
	GLFUNC_ALWAYS_REQUIRED(glNormal3f),
	GLFUNC_ALWAYS_REQUIRED(glNormal3i),
	GLFUNC_ALWAYS_REQUIRED(glNormal3s),
	GLFUNC_ALWAYS_REQUIRED(glNormal3bv),
	GLFUNC_ALWAYS_REQUIRED(glNormal3dv),
	GLFUNC_ALWAYS_REQUIRED(glNormal3fv),
	GLFUNC_ALWAYS_REQUIRED(glNormal3iv),
	GLFUNC_ALWAYS_REQUIRED(glNormal3sv),
	GLFUNC_ALWAYS_REQUIRED(glIndexd),
	GLFUNC_ALWAYS_REQUIRED(glIndexf),
	GLFUNC_ALWAYS_REQUIRED(glIndexi),
	GLFUNC_ALWAYS_REQUIRED(glIndexs),
	GLFUNC_ALWAYS_REQUIRED(glIndexub),
	GLFUNC_ALWAYS_REQUIRED(glIndexdv),
	GLFUNC_ALWAYS_REQUIRED(glIndexfv),
	GLFUNC_ALWAYS_REQUIRED(glIndexiv),
	GLFUNC_ALWAYS_REQUIRED(glIndexsv),
	GLFUNC_ALWAYS_REQUIRED(glIndexubv),
	GLFUNC_ALWAYS_REQUIRED(glColor3b),
	GLFUNC_ALWAYS_REQUIRED(glColor3d),
	GLFUNC_ALWAYS_REQUIRED(glColor3f),
	GLFUNC_ALWAYS_REQUIRED(glColor3i),
	GLFUNC_ALWAYS_REQUIRED(glColor3s),
	GLFUNC_ALWAYS_REQUIRED(glColor3ub),
	GLFUNC_ALWAYS_REQUIRED(glColor3ui),
	GLFUNC_ALWAYS_REQUIRED(glColor3us),
	GLFUNC_ALWAYS_REQUIRED(glColor4b),
	GLFUNC_ALWAYS_REQUIRED(glColor4d),
	GLFUNC_ALWAYS_REQUIRED(glColor4f),
	GLFUNC_ALWAYS_REQUIRED(glColor4i),
	GLFUNC_ALWAYS_REQUIRED(glColor4s),
	GLFUNC_ALWAYS_REQUIRED(glColor4ub),
	GLFUNC_ALWAYS_REQUIRED(glColor4ui),
	GLFUNC_ALWAYS_REQUIRED(glColor4us),
	GLFUNC_ALWAYS_REQUIRED(glColor3bv),
	GLFUNC_ALWAYS_REQUIRED(glColor3dv),
	GLFUNC_ALWAYS_REQUIRED(glColor3fv),
	GLFUNC_ALWAYS_REQUIRED(glColor3iv),
	GLFUNC_ALWAYS_REQUIRED(glColor3sv),
	GLFUNC_ALWAYS_REQUIRED(glColor3ubv),
	GLFUNC_ALWAYS_REQUIRED(glColor3uiv),
	GLFUNC_ALWAYS_REQUIRED(glColor3usv),
	GLFUNC_ALWAYS_REQUIRED(glColor4bv),
	GLFUNC_ALWAYS_REQUIRED(glColor4dv),
	GLFUNC_ALWAYS_REQUIRED(glColor4fv),
	GLFUNC_ALWAYS_REQUIRED(glColor4iv),
	GLFUNC_ALWAYS_REQUIRED(glColor4sv),
	GLFUNC_ALWAYS_REQUIRED(glColor4ubv),
	GLFUNC_ALWAYS_REQUIRED(glColor4uiv),
	GLFUNC_ALWAYS_REQUIRED(glColor4usv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1d),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1f),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1i),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1s),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2d),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2f),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2i),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2s),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3d),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3f),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3i),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3s),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4d),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4f),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4i),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4s),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1dv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1fv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1iv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord1sv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2dv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2fv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2iv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord2sv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3dv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3fv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3iv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord3sv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4dv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4fv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4iv),
	GLFUNC_ALWAYS_REQUIRED(glTexCoord4sv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2d),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2f),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2i),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2s),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3d),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3f),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3i),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3s),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4d),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4f),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4i),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4s),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2dv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2fv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2iv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos2sv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3dv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3fv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3iv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos3sv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4dv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4fv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4iv),
	GLFUNC_ALWAYS_REQUIRED(glRasterPos4sv),
	GLFUNC_ALWAYS_REQUIRED(glRectd),
	GLFUNC_ALWAYS_REQUIRED(glRectf),
	GLFUNC_ALWAYS_REQUIRED(glRecti),
	GLFUNC_ALWAYS_REQUIRED(glRects),
	GLFUNC_ALWAYS_REQUIRED(glRectdv),
	GLFUNC_ALWAYS_REQUIRED(glRectfv),
	GLFUNC_ALWAYS_REQUIRED(glRectiv),
	GLFUNC_ALWAYS_REQUIRED(glRectsv),
	GLFUNC_ALWAYS_REQUIRED(glVertexPointer),
	GLFUNC_ALWAYS_REQUIRED(glNormalPointer),
	GLFUNC_ALWAYS_REQUIRED(glColorPointer),
	GLFUNC_ALWAYS_REQUIRED(glIndexPointer),
	GLFUNC_ALWAYS_REQUIRED(glTexCoordPointer),
	GLFUNC_ALWAYS_REQUIRED(glEdgeFlagPointer),
	GLFUNC_ALWAYS_REQUIRED(glArrayElement),
	GLFUNC_ALWAYS_REQUIRED(glInterleavedArrays),
	GLFUNC_ALWAYS_REQUIRED(glShadeModel),
	GLFUNC_ALWAYS_REQUIRED(glLightf),
	GLFUNC_ALWAYS_REQUIRED(glLighti),
	GLFUNC_ALWAYS_REQUIRED(glLightfv),
	GLFUNC_ALWAYS_REQUIRED(glLightiv),
	GLFUNC_ALWAYS_REQUIRED(glGetLightfv),
	GLFUNC_ALWAYS_REQUIRED(glGetLightiv),
	GLFUNC_ALWAYS_REQUIRED(glLightModelf),
	GLFUNC_ALWAYS_REQUIRED(glLightModeli),
	GLFUNC_ALWAYS_REQUIRED(glLightModelfv),
	GLFUNC_ALWAYS_REQUIRED(glLightModeliv),
	GLFUNC_ALWAYS_REQUIRED(glMaterialf),
	GLFUNC_ALWAYS_REQUIRED(glMateriali),
	GLFUNC_ALWAYS_REQUIRED(glMaterialfv),
	GLFUNC_ALWAYS_REQUIRED(glMaterialiv),
	GLFUNC_ALWAYS_REQUIRED(glGetMaterialfv),
	GLFUNC_ALWAYS_REQUIRED(glGetMaterialiv),
	GLFUNC_ALWAYS_REQUIRED(glColorMaterial),
	GLFUNC_ALWAYS_REQUIRED(glPixelZoom),
	GLFUNC_ALWAYS_REQUIRED(glPixelStoref),
	GLFUNC_ALWAYS_REQUIRED(glPixelTransferf),
	GLFUNC_ALWAYS_REQUIRED(glPixelTransferi),
	GLFUNC_ALWAYS_REQUIRED(glPixelMapfv),
	GLFUNC_ALWAYS_REQUIRED(glPixelMapuiv),
	GLFUNC_ALWAYS_REQUIRED(glPixelMapusv),
	GLFUNC_ALWAYS_REQUIRED(glGetPixelMapfv),
	GLFUNC_ALWAYS_REQUIRED(glGetPixelMapuiv),
	GLFUNC_ALWAYS_REQUIRED(glGetPixelMapusv),
	GLFUNC_ALWAYS_REQUIRED(glBitmap),
	GLFUNC_ALWAYS_REQUIRED(glDrawPixels),
	GLFUNC_ALWAYS_REQUIRED(glCopyPixels),
	GLFUNC_ALWAYS_REQUIRED(glTexGend),
	GLFUNC_ALWAYS_REQUIRED(glTexGenf),
	GLFUNC_ALWAYS_REQUIRED(glTexGeni),
	GLFUNC_ALWAYS_REQUIRED(glTexGendv),
	GLFUNC_ALWAYS_REQUIRED(glTexGenfv),
	GLFUNC_ALWAYS_REQUIRED(glTexGeniv),
	GLFUNC_ALWAYS_REQUIRED(glGetTexGendv),
	GLFUNC_ALWAYS_REQUIRED(glGetTexGenfv),
	GLFUNC_ALWAYS_REQUIRED(glGetTexGeniv),
	GLFUNC_ALWAYS_REQUIRED(glTexEnvf),
	GLFUNC_ALWAYS_REQUIRED(glTexEnvi),
	GLFUNC_ALWAYS_REQUIRED(glTexEnvfv),
	GLFUNC_ALWAYS_REQUIRED(glTexEnviv),
	GLFUNC_ALWAYS_REQUIRED(glGetTexEnvfv),
	GLFUNC_ALWAYS_REQUIRED(glGetTexEnviv),
	GLFUNC_ALWAYS_REQUIRED(glGetTexLevelParameterfv),
	GLFUNC_ALWAYS_REQUIRED(glGetTexLevelParameteriv),
	GLFUNC_ALWAYS_REQUIRED(glTexImage1D),
	GLFUNC_ALWAYS_REQUIRED(glGetTexImage),
	GLFUNC_ALWAYS_REQUIRED(glPrioritizeTextures),
	GLFUNC_ALWAYS_REQUIRED(glAreTexturesResident),
	GLFUNC_ALWAYS_REQUIRED(glTexSubImage1D),
	GLFUNC_ALWAYS_REQUIRED(glCopyTexImage1D),
	GLFUNC_ALWAYS_REQUIRED(glCopyTexSubImage1D),
	GLFUNC_ALWAYS_REQUIRED(glMap1d),
	GLFUNC_ALWAYS_REQUIRED(glMap1f),
	GLFUNC_ALWAYS_REQUIRED(glMap2d),
	GLFUNC_ALWAYS_REQUIRED(glMap2f),
	GLFUNC_ALWAYS_REQUIRED(glGetMapdv),
	GLFUNC_ALWAYS_REQUIRED(glGetMapfv),
	GLFUNC_ALWAYS_REQUIRED(glGetMapiv),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord1d),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord1f),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord1dv),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord1fv),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord2d),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord2f),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord2dv),
	GLFUNC_ALWAYS_REQUIRED(glEvalCoord2fv),
	GLFUNC_ALWAYS_REQUIRED(glMapGrid1d),
	GLFUNC_ALWAYS_REQUIRED(glMapGrid1f),
	GLFUNC_ALWAYS_REQUIRED(glMapGrid2d),
	GLFUNC_ALWAYS_REQUIRED(glMapGrid2f),
	GLFUNC_ALWAYS_REQUIRED(glEvalPoint1),
	GLFUNC_ALWAYS_REQUIRED(glEvalPoint2),
	GLFUNC_ALWAYS_REQUIRED(glEvalMesh1),
	GLFUNC_ALWAYS_REQUIRED(glEvalMesh2),
	GLFUNC_ALWAYS_REQUIRED(glFogf),
	GLFUNC_ALWAYS_REQUIRED(glFogi),
	GLFUNC_ALWAYS_REQUIRED(glFogfv),
	GLFUNC_ALWAYS_REQUIRED(glFogiv),
	GLFUNC_ALWAYS_REQUIRED(glFeedbackBuffer),
	GLFUNC_ALWAYS_REQUIRED(glPassThrough),
	GLFUNC_ALWAYS_REQUIRED(glSelectBuffer),
	GLFUNC_ALWAYS_REQUIRED(glInitNames),
	GLFUNC_ALWAYS_REQUIRED(glLoadName),
	GLFUNC_ALWAYS_REQUIRED(glPushName),
	GLFUNC_ALWAYS_REQUIRED(glPopName),
	GL_ES_FUNC_ALWAYS_REQUIRED(glTexImage2D),
	GL_ES_FUNC_ALWAYS_REQUIRED(glClearColor),
	GL_ES_FUNC_ALWAYS_REQUIRED(glClear),
	GL_ES_FUNC_ALWAYS_REQUIRED(glColorMask),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBlendFunc),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCullFace),
	GL_ES_FUNC_ALWAYS_REQUIRED(glFrontFace),
	GL_ES_FUNC_ALWAYS_REQUIRED(glLineWidth),
	GL_ES_FUNC_ALWAYS_REQUIRED(glPolygonOffset),
	GL_ES_FUNC_ALWAYS_REQUIRED(glScissor),
	GL_ES_FUNC_ALWAYS_REQUIRED(glEnable),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDisable),
	GL_ES_FUNC_ALWAYS_REQUIRED(glIsEnabled),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetBooleanv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetFloatv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glFinish),
	GL_ES_FUNC_ALWAYS_REQUIRED(glFlush),
	GL_ES_FUNC_ALWAYS_REQUIRED(glHint),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDepthFunc),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDepthMask),
	GL_ES_FUNC_ALWAYS_REQUIRED(glViewport),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDrawArrays),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDrawElements),
	GL_ES_FUNC_ALWAYS_REQUIRED(glPixelStorei),
	GL_ES_FUNC_ALWAYS_REQUIRED(glReadPixels),
	GL_ES_FUNC_ALWAYS_REQUIRED(glStencilFunc),
	GL_ES_FUNC_ALWAYS_REQUIRED(glStencilMask),
	GL_ES_FUNC_ALWAYS_REQUIRED(glStencilOp),
	GL_ES_FUNC_ALWAYS_REQUIRED(glClearStencil),
	GL_ES_FUNC_ALWAYS_REQUIRED(glTexParameterf),
	GL_ES_FUNC_ALWAYS_REQUIRED(glTexParameteri),
	GL_ES_FUNC_ALWAYS_REQUIRED(glTexParameterfv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glTexParameteriv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetTexParameterfv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetTexParameteriv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGenTextures),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDeleteTextures),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBindTexture),
	GL_ES_FUNC_ALWAYS_REQUIRED(glIsTexture),
	GL_ES_FUNC_ALWAYS_REQUIRED(glTexSubImage2D),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCopyTexImage2D),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCopyTexSubImage2D),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glReadBuffer),
	GL_ES32_FUNC_ALWAYS_REQUIRED(glGetPointerv),

	// gl_1_2
	GL_ES3_FUNC_ALWAYS_REQUIRED(glCopyTexSubImage3D),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glDrawRangeElements),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glTexImage3D),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glTexSubImage3D),

	// gl_1_3
	GLFUNC_ALWAYS_REQUIRED(glClientActiveTexture),
	GLFUNC_ALWAYS_REQUIRED(glCompressedTexImage1D),
	GLFUNC_ALWAYS_REQUIRED(glCompressedTexSubImage1D),
	GLFUNC_ALWAYS_REQUIRED(glGetCompressedTexImage),
	GLFUNC_ALWAYS_REQUIRED(glLoadTransposeMatrixd),
	GLFUNC_ALWAYS_REQUIRED(glLoadTransposeMatrixf),
	GLFUNC_ALWAYS_REQUIRED(glMultTransposeMatrixd),
	GLFUNC_ALWAYS_REQUIRED(glMultTransposeMatrixf),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1d),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1dv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1f),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1fv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1i),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1iv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1s),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord1sv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2d),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2dv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2f),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2fv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2i),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2iv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2s),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord2sv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3d),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3dv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3f),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3fv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3i),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3iv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3s),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord3sv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4d),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4dv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4f),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4fv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4i),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4iv),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4s),
	GLFUNC_ALWAYS_REQUIRED(glMultiTexCoord4sv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glSampleCoverage),
	GL_ES_FUNC_ALWAYS_REQUIRED(glActiveTexture),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCompressedTexImage2D),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCompressedTexSubImage2D),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glCompressedTexImage3D),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glCompressedTexSubImage3D),

	// gl_1_4
	GLFUNC_ALWAYS_REQUIRED(glFogCoordPointer),
	GLFUNC_ALWAYS_REQUIRED(glFogCoordd),
	GLFUNC_ALWAYS_REQUIRED(glFogCoorddv),
	GLFUNC_ALWAYS_REQUIRED(glFogCoordf),
	GLFUNC_ALWAYS_REQUIRED(glFogCoordfv),
	GLFUNC_ALWAYS_REQUIRED(glMultiDrawArrays),
	GLFUNC_ALWAYS_REQUIRED(glMultiDrawElements),
	GLFUNC_ALWAYS_REQUIRED(glPointParameterf),
	GLFUNC_ALWAYS_REQUIRED(glPointParameterfv),
	GLFUNC_ALWAYS_REQUIRED(glPointParameteri),
	GLFUNC_ALWAYS_REQUIRED(glPointParameteriv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3b),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3bv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3d),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3dv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3f),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3fv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3i),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3iv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3s),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3sv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3ub),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3ubv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3ui),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3uiv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3us),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColor3usv),
	GLFUNC_ALWAYS_REQUIRED(glSecondaryColorPointer),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2d),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2dv),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2f),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2fv),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2i),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2iv),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2s),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos2sv),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3d),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3dv),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3f),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3fv),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3i),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3iv),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3s),
	GLFUNC_ALWAYS_REQUIRED(glWindowPos3sv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBlendColor),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBlendEquation),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBlendFuncSeparate),

	// gl_1_5
	GLFUNC_ALWAYS_REQUIRED(glGetBufferSubData),
	GLFUNC_ALWAYS_REQUIRED(glGetQueryObjectiv),
	GLFUNC_ALWAYS_REQUIRED(glMapBuffer),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBindBuffer),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBufferData),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBufferSubData),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDeleteBuffers),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGenBuffers),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetBufferParameteriv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glIsBuffer),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glBeginQuery),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glDeleteQueries),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glEndQuery),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glGenQueries),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glIsQuery),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glGetQueryiv),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glGetQueryObjectuiv),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glGetBufferPointerv),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glUnmapBuffer),

	// gl_2_0
	GLFUNC_ALWAYS_REQUIRED(glGetVertexAttribdv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib1d),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib1dv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib1s),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib1sv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib2d),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib2dv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib2s),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib2sv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib3d),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib3dv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib3s),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib3sv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4Nbv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4Niv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4Nsv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4Nub),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4Nubv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4Nuiv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4Nusv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4bv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4d),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4dv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4iv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4s),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4sv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4ubv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4uiv),
	GLFUNC_ALWAYS_REQUIRED(glVertexAttrib4usv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glAttachShader),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBindAttribLocation),
	GL_ES_FUNC_ALWAYS_REQUIRED(glBlendEquationSeparate),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCompileShader),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCreateProgram),
	GL_ES_FUNC_ALWAYS_REQUIRED(glCreateShader),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDeleteProgram),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDeleteShader),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDetachShader),
	GL_ES_FUNC_ALWAYS_REQUIRED(glDisableVertexAttribArray),
	GL_ES_FUNC_ALWAYS_REQUIRED(glEnableVertexAttribArray),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetActiveAttrib),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetActiveUniform),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetAttachedShaders),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetAttribLocation),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetProgramInfoLog),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetProgramiv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetShaderInfoLog),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetShaderSource),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetShaderiv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetUniformLocation),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetUniformfv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetUniformiv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetVertexAttribPointerv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetVertexAttribfv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glGetVertexAttribiv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glIsProgram),
	GL_ES_FUNC_ALWAYS_REQUIRED(glIsShader),
	GL_ES_FUNC_ALWAYS_REQUIRED(glLinkProgram),
	GL_ES_FUNC_ALWAYS_REQUIRED(glShaderSource),
	GL_ES_FUNC_ALWAYS_REQUIRED(glStencilFuncSeparate),
	GL_ES_FUNC_ALWAYS_REQUIRED(glStencilMaskSeparate),
	GL_ES_FUNC_ALWAYS_REQUIRED(glStencilOpSeparate),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform1f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform1fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform1i),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform1iv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform2f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform2fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform2i),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform2iv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform3f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform3fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform3i),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform3iv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform4f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform4fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform4i),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniform4iv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniformMatrix2fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniformMatrix3fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUniformMatrix4fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glUseProgram),
	GL_ES_FUNC_ALWAYS_REQUIRED(glValidateProgram),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib1f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib1fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib2f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib2fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib3f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib3fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib4f),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttrib4fv),
	GL_ES_FUNC_ALWAYS_REQUIRED(glVertexAttribPointer),
	GL_ES3_FUNC_ALWAYS_REQUIRED(glDrawBuffers),

	// gl_2_1
	GLFUNC_ALWAYS_REQUIRED(glUniformMatrix2x3fv),
	GLFUNC_ALWAYS_REQUIRED(glUniformMatrix2x4fv),
	GLFUNC_ALWAYS_REQUIRED(glUniformMatrix3x2fv),
	GLFUNC_ALWAYS_REQUIRED(glUniformMatrix3x4fv),
	GLFUNC_ALWAYS_REQUIRED(glUniformMatrix4x2fv),
	GLFUNC_ALWAYS_REQUIRED(glUniformMatrix4x3fv),

	// gl_3_0
	GLFUNC_REQUIRES(glBeginConditionalRender,      "VERSION_3_0"),
	GLFUNC_REQUIRES(glBindFragDataLocation,        "VERSION_3_0"),
	GLFUNC_REQUIRES(glClampColor,                  "VERSION_3_0"),
	GLFUNC_REQUIRES(glEndConditionalRender,        "VERSION_3_0"),
	GLFUNC_REQUIRES(glGetBooleani_v,               "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI1i,             "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI1iv,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI1ui,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI1uiv,           "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI2i,             "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI2iv,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI2ui,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI2uiv,           "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI3i,             "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI3iv,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI3ui,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI3uiv,           "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI4bv,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI4sv,            "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI4ubv,           "VERSION_3_0"),
	GLFUNC_REQUIRES(glVertexAttribI4usv,           "VERSION_3_0"),
	GLFUNC_REQUIRES(glBeginTransformFeedback,      "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glClearBufferfi,               "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glClearBufferfv,               "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glClearBufferiv,               "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glClearBufferuiv,              "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glEndTransformFeedback,        "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetFragDataLocation,         "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetStringi,                  "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetTransformFeedbackVarying, "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetUniformuiv,               "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetVertexAttribIiv,          "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetVertexAttribIuiv,         "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glTransformFeedbackVaryings,   "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform1ui,                  "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform1uiv,                 "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform2ui,                  "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform2uiv,                 "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform3ui,                  "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform3uiv,                 "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform4ui,                  "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniform4uiv,                 "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glVertexAttribI4i,             "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glVertexAttribI4iv,            "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glVertexAttribI4ui,            "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glVertexAttribI4uiv,           "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glVertexAttribIPointer,        "VERSION_3_0 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glColorMaski,                  "VERSION_3_0 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glDisablei,                    "VERSION_3_0 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glEnablei,                     "VERSION_3_0 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glGetTexParameterIiv,          "VERSION_3_0 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glGetTexParameterIuiv,         "VERSION_3_0 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glIsEnabledi,                  "VERSION_3_0 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glTexParameterIiv,             "VERSION_3_0 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glTexParameterIuiv,            "VERSION_3_0 |VERSION_GLES_3_2"),


	// gl_3_1
	GLFUNC_REQUIRES(glPrimitiveRestartIndex, "VERSION_3_1"),
	GLFUNC_REQUIRES(glDrawArraysInstanced,   "VERSION_3_1 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glDrawElementsInstanced, "VERSION_3_1 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glTexBuffer,             "VERSION_3_1 |VERSION_GLES_3_2"),

	// gl_3_2
	GLFUNC_REQUIRES(glGetBufferParameteri64v, "VERSION_3_2 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetInteger64i_v,        "VERSION_3_2 |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glFramebufferTexture,     "VERSION_3_2 |VERSION_GLES_3_2"),

	// gl_4_2
	GLFUNC_REQUIRES(glDrawArraysInstancedBaseInstance,             "VERSION_4_2"),
	GLFUNC_REQUIRES(glDrawElementsInstancedBaseInstance,           "VERSION_4_2"),
	GLFUNC_REQUIRES(glDrawElementsInstancedBaseVertexBaseInstance, "VERSION_4_2"),
	GLFUNC_REQUIRES(glGetInternalformativ,                         "VERSION_4_2"),
	GLFUNC_REQUIRES(glGetActiveAtomicCounterBufferiv,              "VERSION_4_2"),
	GLFUNC_REQUIRES(glBindImageTexture,                            "VERSION_4_2"),
	GLFUNC_REQUIRES(glMemoryBarrier,                               "VERSION_4_2"),
	GLFUNC_REQUIRES(glTexStorage1D,                                "VERSION_4_2"),
	GLFUNC_REQUIRES(glTexStorage2D,                                "VERSION_4_2"),
	GLFUNC_REQUIRES(glTexStorage3D,                                "VERSION_4_2"),
	GLFUNC_REQUIRES(glDrawTransformFeedbackInstanced,              "VERSION_4_2"),
	GLFUNC_REQUIRES(glDrawTransformFeedbackStreamInstanced,        "VERSION_4_2"),


	// gl_4_3
	GLFUNC_REQUIRES(glClearBufferData,                 "VERSION_4_3"),
	GLFUNC_REQUIRES(glClearBufferSubData,              "VERSION_4_3"),
	GLFUNC_REQUIRES(glDispatchCompute,                 "VERSION_4_3"),
	GLFUNC_REQUIRES(glDispatchComputeIndirect,         "VERSION_4_3"),
	GLFUNC_REQUIRES(glCopyImageSubData,                "VERSION_4_3"),
	GLFUNC_REQUIRES(glFramebufferParameteri,           "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetFramebufferParameteriv,       "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetInternalformati64v,           "VERSION_4_3"),
	GLFUNC_REQUIRES(glInvalidateTexSubImage,           "VERSION_4_3"),
	GLFUNC_REQUIRES(glInvalidateTexImage,              "VERSION_4_3"),
	GLFUNC_REQUIRES(glInvalidateBufferSubData,         "VERSION_4_3"),
	GLFUNC_REQUIRES(glInvalidateBufferData,            "VERSION_4_3"),
	GLFUNC_REQUIRES(glInvalidateFramebuffer,           "VERSION_4_3"),
	GLFUNC_REQUIRES(glInvalidateSubFramebuffer,        "VERSION_4_3"),
	GLFUNC_REQUIRES(glMultiDrawArraysIndirect,         "VERSION_4_3"),
	GLFUNC_REQUIRES(glMultiDrawElementsIndirect,       "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetProgramInterfaceiv,           "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetProgramResourceIndex,         "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetProgramResourceName,          "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetProgramResourceiv,            "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetProgramResourceLocation,      "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetProgramResourceLocationIndex, "VERSION_4_3"),
	GLFUNC_REQUIRES(glShaderStorageBlockBinding,       "VERSION_4_3"),
	GLFUNC_REQUIRES(glTexBufferRange,                  "VERSION_4_3"),
	GLFUNC_REQUIRES(glTexStorage2DMultisample,         "VERSION_4_3"),
	GLFUNC_REQUIRES(glTexStorage3DMultisample,         "VERSION_4_3"),
	GLFUNC_REQUIRES(glTextureView,                     "VERSION_4_3"),
	GLFUNC_REQUIRES(glBindVertexBuffer,                "VERSION_4_3"),
	GLFUNC_REQUIRES(glVertexAttribFormat,              "VERSION_4_3"),
	GLFUNC_REQUIRES(glVertexAttribIFormat,             "VERSION_4_3"),
	GLFUNC_REQUIRES(glVertexAttribLFormat,             "VERSION_4_3"),
	GLFUNC_REQUIRES(glVertexAttribBinding,             "VERSION_4_3"),
	GLFUNC_REQUIRES(glVertexBindingDivisor,            "VERSION_4_3"),
	GLFUNC_REQUIRES(glDebugMessageControl,             "VERSION_4_3"),
	GLFUNC_REQUIRES(glDebugMessageInsert,              "VERSION_4_3"),
	GLFUNC_REQUIRES(glDebugMessageCallback,            "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetDebugMessageLog,              "VERSION_4_3"),
	GLFUNC_REQUIRES(glPushDebugGroup,                  "VERSION_4_3"),
	GLFUNC_REQUIRES(glPopDebugGroup,                   "VERSION_4_3"),
	GLFUNC_REQUIRES(glObjectLabel,                     "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetObjectLabel,                  "VERSION_4_3"),
	GLFUNC_REQUIRES(glObjectPtrLabel,                  "VERSION_4_3"),
	GLFUNC_REQUIRES(glGetObjectPtrLabel,               "VERSION_4_3"),

	// gl_4_4
	GLFUNC_REQUIRES(glBufferStorage,     "VERSION_4_4"),
	GLFUNC_REQUIRES(glClearTexImage,     "VERSION_4_4"),
	GLFUNC_REQUIRES(glClearTexSubImage,  "VERSION_4_4"),
	GLFUNC_REQUIRES(glBindBuffersBase,   "VERSION_4_4"),
	GLFUNC_REQUIRES(glBindBuffersRange,  "VERSION_4_4"),
	GLFUNC_REQUIRES(glBindTextures,      "VERSION_4_4"),
	GLFUNC_REQUIRES(glBindSamplers,      "VERSION_4_4"),
	GLFUNC_REQUIRES(glBindImageTextures, "VERSION_4_4"),
	GLFUNC_REQUIRES(glBindVertexBuffers, "VERSION_4_4"),

	// gl_4_5
	GLFUNC_REQUIRES(glClipControl,                              "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateTransformFeedbacks,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glTransformFeedbackBufferBase,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glTransformFeedbackBufferRange,             "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTransformFeedbackiv,                   "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTransformFeedbacki_v,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTransformFeedbacki64_v,                "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateBuffers,                            "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedBufferStorage,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedBufferData,                          "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedBufferSubData,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glCopyNamedBufferSubData,                   "VERSION_4_5"),
	GLFUNC_REQUIRES(glClearNamedBufferData,                     "VERSION_4_5"),
	GLFUNC_REQUIRES(glClearNamedBufferSubData,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glMapNamedBuffer,                           "VERSION_4_5"),
	GLFUNC_REQUIRES(glMapNamedBufferRange,                      "VERSION_4_5"),
	GLFUNC_REQUIRES(glUnmapNamedBuffer,                         "VERSION_4_5"),
	GLFUNC_REQUIRES(glFlushMappedNamedBufferRange,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetNamedBufferParameteriv,                "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetNamedBufferParameteri64v,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetNamedBufferPointerv,                   "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetNamedBufferSubData,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateFramebuffers,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedFramebufferRenderbuffer,             "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedFramebufferParameteri,               "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedFramebufferTexture,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedFramebufferTextureLayer,             "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedFramebufferDrawBuffer,               "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedFramebufferDrawBuffers,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedFramebufferReadBuffer,               "VERSION_4_5"),
	GLFUNC_REQUIRES(glInvalidateNamedFramebufferData,           "VERSION_4_5"),
	GLFUNC_REQUIRES(glInvalidateNamedFramebufferSubData,        "VERSION_4_5"),
	GLFUNC_REQUIRES(glClearNamedFramebufferiv,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glClearNamedFramebufferuiv,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glClearNamedFramebufferfv,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glClearNamedFramebufferfi,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glBlitNamedFramebuffer,                     "VERSION_4_5"),
	GLFUNC_REQUIRES(glCheckNamedFramebufferStatus,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetNamedFramebufferParameteriv,           "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetNamedFramebufferAttachmentParameteriv, "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateRenderbuffers,                      "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedRenderbufferStorage,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glNamedRenderbufferStorageMultisample,      "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetNamedRenderbufferParameteriv,          "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateTextures,                           "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureBuffer,                            "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureBufferRange,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureStorage1D,                         "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureStorage2D,                         "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureStorage3D,                         "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureStorage2DMultisample,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureStorage3DMultisample,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureSubImage1D,                        "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureSubImage2D,                        "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureSubImage3D,                        "VERSION_4_5"),
	GLFUNC_REQUIRES(glCompressedTextureSubImage1D,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glCompressedTextureSubImage2D,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glCompressedTextureSubImage3D,              "VERSION_4_5"),
	GLFUNC_REQUIRES(glCopyTextureSubImage1D,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glCopyTextureSubImage2D,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glCopyTextureSubImage3D,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureParameterf,                        "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureParameterfv,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureParameteri,                        "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureParameterIiv,                      "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureParameterIuiv,                     "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureParameteriv,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glGenerateTextureMipmap,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glBindTextureUnit,                          "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureImage,                          "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetCompressedTextureImage,                "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureLevelParameterfv,               "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureLevelParameteriv,               "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureParameterfv,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureParameterIiv,                   "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureParameterIuiv,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureParameteriv,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateVertexArrays,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glDisableVertexArrayAttrib,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glEnableVertexArrayAttrib,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayElementBuffer,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayVertexBuffer,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayVertexBuffers,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayAttribBinding,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayAttribFormat,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayAttribIFormat,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayAttribLFormat,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glVertexArrayBindingDivisor,                "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetVertexArrayiv,                         "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetVertexArrayIndexediv,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetVertexArrayIndexed64iv,                "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateSamplers,                           "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateProgramPipelines,                   "VERSION_4_5"),
	GLFUNC_REQUIRES(glCreateQueries,                            "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetQueryBufferObjecti64v,                 "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetQueryBufferObjectiv,                   "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetQueryBufferObjectui64v,                "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetQueryBufferObjectuiv,                  "VERSION_4_5"),
	GLFUNC_REQUIRES(glMemoryBarrierByRegion,                    "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetTextureSubImage,                       "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetCompressedTextureSubImage,             "VERSION_4_5"),
	GLFUNC_REQUIRES(glGetGraphicsResetStatus,                   "VERSION_4_5"),
	GLFUNC_REQUIRES(glReadnPixels,                              "VERSION_4_5"),
	GLFUNC_REQUIRES(glTextureBarrier,                           "VERSION_4_5"),
	// AMD's video driver is trash and doesn't expose these function pointers
	// Remove them for now until they learn how to implement the spec properly.
	// GLFUNC_REQUIRES(glGetnCompressedTexImage,                   "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnTexImage,                             "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnUniformdv,                            "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnUniformfv,                            "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnUniformiv,                            "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnUniformuiv,                           "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnMapdv,                                "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnMapfv,                                "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnMapiv,                                "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnPixelMapfv,                           "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnPixelMapuiv,                          "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnPixelMapusv,                          "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnPolygonStipple,                       "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnColorTable,                           "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnConvolutionFilter,                    "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnSeparableFilter,                      "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnHistogram,                            "VERSION_4_5"),
	// GLFUNC_REQUIRES(glGetnMinmax,                               "VERSION_4_5"),

	// ARB_uniform_buffer_object
	GLFUNC_REQUIRES(glGetActiveUniformName,      "GL_ARB_uniform_buffer_object"),
	GLFUNC_REQUIRES(glBindBufferBase,            "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glBindBufferRange,           "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetActiveUniformBlockName, "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetActiveUniformBlockiv,   "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetActiveUniformsiv,       "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetIntegeri_v,             "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetUniformBlockIndex,      "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetUniformIndices,         "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glUniformBlockBinding,       "GL_ARB_uniform_buffer_object |VERSION_GLES_3"),

	// ARB_sampler_objects
	GLFUNC_REQUIRES(glBindSampler,             "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glDeleteSamplers,          "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGenSamplers,             "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetSamplerParameterfv,   "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetSamplerParameteriv,   "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glIsSampler,               "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glSamplerParameterf,       "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glSamplerParameterfv,      "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glSamplerParameteri,       "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glSamplerParameteriv,      "GL_ARB_sampler_objects |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetSamplerParameterIiv,  "GL_ARB_sampler_objects |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glGetSamplerParameterIuiv, "GL_ARB_sampler_objects |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glSamplerParameterIiv,     "GL_ARB_sampler_objects |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glSamplerParameterIuiv,    "GL_ARB_sampler_objects |VERSION_GLES_3_2"),

	// ARB_map_buffer_range
	GLFUNC_REQUIRES(glFlushMappedBufferRange, "GL_ARB_map_buffer_range |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glMapBufferRange,         "GL_ARB_map_buffer_range |VERSION_GLES_3"),

	// ARB_vertex_array_object
	GLFUNC_REQUIRES(glBindVertexArray,    "GL_ARB_vertex_array_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glDeleteVertexArrays, "GL_ARB_vertex_array_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGenVertexArrays,    "GL_ARB_vertex_array_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glIsVertexArray,      "GL_ARB_vertex_array_object |VERSION_GLES_3"),

	// APPLE_vertex_array_object
	GLFUNC_SUFFIX(glBindVertexArray,    APPLE, "GL_APPLE_vertex_array_object !GL_ARB_vertex_array_object"),
	GLFUNC_SUFFIX(glDeleteVertexArrays, APPLE, "GL_APPLE_vertex_array_object !GL_ARB_vertex_array_object"),
	GLFUNC_SUFFIX(glGenVertexArrays,    APPLE, "GL_APPLE_vertex_array_object !GL_ARB_vertex_array_object"),
	GLFUNC_SUFFIX(glIsVertexArray,      APPLE, "GL_APPLE_vertex_array_object !GL_ARB_vertex_array_object"),

	// ARB_framebuffer_object
	GLFUNC_REQUIRES(glFramebufferTexture1D,                "GL_ARB_framebuffer_object"),
	GLFUNC_REQUIRES(glFramebufferTexture3D,                "GL_ARB_framebuffer_object"),
	GLFUNC_REQUIRES(glBindFramebuffer,                     "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glBindRenderbuffer,                    "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glBlitFramebuffer,                     "GL_ARB_framebuffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glCheckFramebufferStatus,              "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glDeleteFramebuffers,                  "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glDeleteRenderbuffers,                 "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glFramebufferRenderbuffer,             "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glFramebufferTexture2D,                "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glFramebufferTextureLayer,             "GL_ARB_framebuffer_object |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGenFramebuffers,                     "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glGenRenderbuffers,                    "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glGenerateMipmap,                      "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glGetFramebufferAttachmentParameteriv, "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glGetRenderbufferParameteriv,          "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glIsFramebuffer,                       "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glIsRenderbuffer,                      "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glRenderbufferStorage,                 "GL_ARB_framebuffer_object |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glRenderbufferStorageMultisample,      "GL_ARB_framebuffer_object |VERSION_GLES_3"),

	// ARB_get_program_binary
	GLFUNC_REQUIRES(glGetProgramBinary,  "GL_ARB_get_program_binary |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glProgramBinary,     "GL_ARB_get_program_binary |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glProgramParameteri, "GL_ARB_get_program_binary |VERSION_GLES_3"),

	// ARB_sync
	GLFUNC_REQUIRES(glClientWaitSync, "GL_ARB_sync |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glDeleteSync,     "GL_ARB_sync |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glFenceSync,      "GL_ARB_sync |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetInteger64v,  "GL_ARB_sync |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glGetSynciv,      "GL_ARB_sync |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glIsSync,         "GL_ARB_sync |VERSION_GLES_3"),
	GLFUNC_REQUIRES(glWaitSync,       "GL_ARB_sync |VERSION_GLES_3"),

	// ARB_texture_multisample
	GLFUNC_REQUIRES(glTexImage2DMultisample, "GL_ARB_texture_multisample"),
	GLFUNC_REQUIRES(glTexImage3DMultisample, "GL_ARB_texture_multisample"),
	GLFUNC_REQUIRES(glGetMultisamplefv,      "GL_ARB_texture_multisample"),
	GLFUNC_REQUIRES(glSampleMaski,           "GL_ARB_texture_multisample"),

	// ARB_texture_storage_multisample
	GLFUNC_REQUIRES(glTexStorage2DMultisample, "GL_ARB_texture_storage_multisample !VERSION_4_3 |VERSION_GLES_3_1"),
	GLFUNC_REQUIRES(glTexStorage3DMultisample, "GL_ARB_texture_storage_multisample !VERSION_4_3 |VERSION_GLES_3_2"),
	GLFUNC_SUFFIX(glTexStorage3DMultisample, OES, "GL_OES_texture_storage_multisample_2d_array !VERSION_GLES_3_2"),

	// ARB_ES2_compatibility
	GLFUNC_REQUIRES(glClearDepthf,              "GL_ARB_ES2_compatibility |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glDepthRangef,              "GL_ARB_ES2_compatibility |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glGetShaderPrecisionFormat, "GL_ARB_ES2_compatibility |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glReleaseShaderCompiler,    "GL_ARB_ES2_compatibility |VERSION_GLES_2"),
	GLFUNC_REQUIRES(glShaderBinary,             "GL_ARB_ES2_compatibility |VERSION_GLES_2"),

	// NV_primitive_restart
	GLFUNC_REQUIRES(glPrimitiveRestartIndexNV, "GL_NV_primitive_restart"),
	GLFUNC_REQUIRES(glPrimitiveRestartNV,      "GL_NV_primitive_restart"),

	// ARB_blend_func_extended
	GLFUNC_REQUIRES(glBindFragDataLocationIndexed, "GL_ARB_blend_func_extended"),
	GLFUNC_REQUIRES(glGetFragDataIndex,            "GL_ARB_blend_func_extended"),

	// ARB_viewport_array
	GLFUNC_REQUIRES(glDepthRangeArrayv,  "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glDepthRangeIndexed, "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glGetDoublei_v,      "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glGetFloati_v,       "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glScissorArrayv,     "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glScissorIndexed,    "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glScissorIndexedv,   "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glViewportArrayv,    "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glViewportIndexedf,  "GL_ARB_viewport_array"),
	GLFUNC_REQUIRES(glViewportIndexedfv, "GL_ARB_viewport_array"),

	// ARB_draw_elements_base_vertex
	GLFUNC_REQUIRES(glDrawElementsBaseVertex,          "GL_ARB_draw_elements_base_vertex |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glDrawElementsInstancedBaseVertex, "GL_ARB_draw_elements_base_vertex |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glDrawRangeElementsBaseVertex,     "GL_ARB_draw_elements_base_vertex |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glMultiDrawElementsBaseVertex,     "GL_ARB_draw_elements_base_vertex"),

	// OES_draw_elements_base_vertex
	GLFUNC_SUFFIX(glDrawElementsBaseVertex,          OES, "GL_OES_draw_elements_base_vertex !VERSION_GLES_3_2"),
	GLFUNC_SUFFIX(glDrawElementsInstancedBaseVertex, OES, "GL_OES_draw_elements_base_vertex VERSION_GLES_3 !VERSION_GLES_3_2"),
	GLFUNC_SUFFIX(glDrawRangeElementsBaseVertex,     OES, "GL_OES_draw_elements_base_vertex VERSION_GLES_3 !VERSION_GLES_3_2"),
	GLFUNC_SUFFIX(glMultiDrawElementsBaseVertex,     OES, "GL_OES_draw_elements_base_vertex GL_EXT_multi_draw_arrays"),

	// EXT_draw_elements_base_vertex
	GLFUNC_SUFFIX(glDrawElementsBaseVertex,          EXT, "GL_EXT_draw_elements_base_vertex !GL_OES_draw_elements_base_vertex !VERSION_GLES_3_2"),
	GLFUNC_SUFFIX(glDrawElementsInstancedBaseVertex, EXT, "GL_EXT_draw_elements_base_vertex VERSION_GLES_3 !GL_OES_draw_elements_base_vertex !VERSION_GLES_3_2"),
	GLFUNC_SUFFIX(glDrawRangeElementsBaseVertex,     EXT, "GL_EXT_draw_elements_base_vertex VERSION_GLES_3 !GL_OES_draw_elements_base_vertex !VERSION_GLES_3_2"),
	GLFUNC_SUFFIX(glMultiDrawElementsBaseVertex,     EXT, "GL_EXT_draw_elements_base_vertex GL_EXT_multi_draw_arrays !GL_OES_draw_elements_base_vertex !VERSION_GLES_3_2"),

	// ARB_sample_shading
	GLFUNC_SUFFIX(glMinSampleShading, ARB, "GL_ARB_sample_shading"),

	// OES_sample_shading
	GLFUNC_SUFFIX(glMinSampleShading, OES, "GL_OES_sample_shading !VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glMinSampleShading,    "VERSION_GLES_3_2"),

	// ARB_debug_output
	GLFUNC_REQUIRES(glDebugMessageCallbackARB, "GL_ARB_debug_output"),
	GLFUNC_REQUIRES(glDebugMessageControlARB,  "GL_ARB_debug_output"),
	GLFUNC_REQUIRES(glDebugMessageInsertARB,   "GL_ARB_debug_output"),
	GLFUNC_REQUIRES(glGetDebugMessageLogARB,   "GL_ARB_debug_output"),

	// KHR_debug
	GLFUNC_SUFFIX(glDebugMessageCallback, KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glDebugMessageControl,  KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glDebugMessageInsert,   KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glGetDebugMessageLog,   KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glGetObjectLabel,       KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glGetObjectPtrLabel,    KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glObjectLabel,          KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glObjectPtrLabel,       KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glPopDebugGroup,        KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_SUFFIX(glPushDebugGroup,       KHR, "GL_KHR_debug VERSION_GLES_3"),
	GLFUNC_REQUIRES(glDebugMessageCallback, "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glDebugMessageControl,  "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glDebugMessageInsert,   "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glGetDebugMessageLog,   "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glGetObjectLabel,       "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glGetObjectPtrLabel,    "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glObjectLabel,          "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glObjectPtrLabel,       "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glPopDebugGroup,        "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),
	GLFUNC_REQUIRES(glPushDebugGroup,       "GL_KHR_debug !VERSION_GLES_3 !VERSION_GL_4_3 |VERSION_GLES_3_2"),

	// ARB_buffer_storage
	GLFUNC_REQUIRES(glBufferStorage,         "GL_ARB_buffer_storage !VERSION_4_4"),
	GLFUNC_SUFFIX(glNamedBufferStorage, EXT, "GL_ARB_buffer_storage GL_EXT_direct_state_access !VERSION_4_5"),

	// EXT_buffer_storage
	GLFUNC_SUFFIX(glBufferStorage, EXT, "GL_EXT_buffer_storage !GL_ARB_buffer_storage !VERSION_4_4"),

	// EXT_geometry_shader
	GLFUNC_SUFFIX(glFramebufferTexture, EXT, "GL_EXT_geometry_shader !VERSION_3_2"),

	// NV_occlusion_query_samples
	GLFUNC_REQUIRES(glGenOcclusionQueriesNV,    "GL_NV_occlusion_query_samples"),
	GLFUNC_REQUIRES(glDeleteOcclusionQueriesNV, "GL_NV_occlusion_query_samples"),
	GLFUNC_REQUIRES(glIsOcclusionQueryNV,       "GL_NV_occlusion_query_samples"),
	GLFUNC_REQUIRES(glBeginOcclusionQueryNV,    "GL_NV_occlusion_query_samples"),
	GLFUNC_REQUIRES(glEndOcclusionQueryNV,      "GL_NV_occlusion_query_samples"),
	GLFUNC_REQUIRES(glGetOcclusionQueryivNV,    "GL_NV_occlusion_query_samples"),
	GLFUNC_REQUIRES(glGetOcclusionQueryuivNV,   "GL_NV_occlusion_query_samples"),

	// ARB_clip_control
	GLFUNC_REQUIRES(glClipControl, "GL_ARB_clip_control !VERSION_4_5"),

	// ARB_copy_image
	GLFUNC_REQUIRES(glCopyImageSubData, "GL_ARB_copy_image !VERSION_4_3 |VERSION_GLES_3_2"),

	// NV_copy_image
	GLFUNC_SUFFIX(glCopyImageSubData, NV, "GL_NV_copy_image !GL_ARB_copy_image !VERSION_GLES_3_2"),

	// OES_copy_image
	GLFUNC_SUFFIX(glCopyImageSubData, OES, "GL_OES_copy_image !VERSION_GLES_3_2"),

	// EXT_copy_image
	GLFUNC_SUFFIX(glCopyImageSubData, EXT, "GL_EXT_copy_image !GL_OES_copy_image !VERSION_GLES_3_2"),

	// EXT_texture_buffer
	GLFUNC_SUFFIX(glTexBuffer, OES, "GL_OES_texture_buffer !VERSION_GLES_3_2"),

	// EXT_texture_buffer
	GLFUNC_SUFFIX(glTexBuffer, EXT, "GL_EXT_texture_buffer !GL_OES_texture_buffer !VERSION_GLES_3_2"),

	// EXT_blend_func_extended
	GLFUNC_SUFFIX(glBindFragDataLocationIndexed, EXT, "GL_EXT_blend_func_extended"),
	GLFUNC_SUFFIX(glGetFragDataIndex, EXT,            "GL_EXT_blend_func_extended"),

	// ARB_shader_storage_buffer_object
	GLFUNC_REQUIRES(glShaderStorageBlockBinding, "ARB_shader_storage_buffer_object !VERSION_4_3"),
};

namespace GLExtensions
{
	// Private members and functions
	static bool _isES;
	static u32 _GLVersion;
	static std::unordered_map<std::string, bool> m_extension_list;

	// Private initialization functions
	bool InitFunctionPointers();

	// Initializes the extension list the old way
	static void InitExtensionList21()
	{
		const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
		std::string tmp(extensions);
		std::istringstream buffer(tmp);

		while (buffer >> tmp)
			m_extension_list[tmp] = true;
	}

	static void InitExtensionList()
	{
		m_extension_list.clear();
		if (_isES)
		{
			switch (_GLVersion)
			{
				default:
				case 320:
					m_extension_list["VERSION_GLES_3_2"] = true;
				case 310:
					m_extension_list["VERSION_GLES_3_1"] = true;
				case 300:
					m_extension_list["VERSION_GLES_3"] = true;
				break;
			}

			// We always have ES 2.0
			m_extension_list["VERSION_GLES_2"] = true;
		}
		else
		{
			// Some OpenGL implementations chose to not expose core extensions as extensions
			// Let's add them to the list manually depending on which version of OpenGL we have
			// We need to be slightly careful here
			// When an extension got merged in to core, the naming may have changed

			// This has intentional fall through
			switch (_GLVersion)
			{
				default:
				case 450:
				{
					std::string gl450exts[] = {
						"GL_ARB_ES3_1_compatibility",
						"GL_ARB_clip_control",
						"GL_ARB_conditional_render_inverted",
						"GL_ARB_cull_distance",
						"GL_ARB_derivative_control",
						"GL_ARB_direct_state_access",
						"GL_ARB_get_texture_sub_image",
						"GL_ARB_robustness",
						"GL_ARB_shader_texture_image_samples",
						"GL_ARB_texture_barrier",
						"VERSION_4_5",
					};
					for (auto it : gl450exts)
						m_extension_list[it] = true;
				}
				case 440:
				{
					std::string gl440exts[] = {
						"GL_ARB_buffer_storage",
						"GL_ARB_clear_texture",
						"GL_ARB_enhanced_layouts",
						"GL_ARB_multi_bind",
						"GL_ARB_query_buffer_object",
						"GL_ARB_texture_mirror_clamp_to_edge",
						"GL_ARB_texture_stencil8",
						"GL_ARB_vertex_type_10f_11f_11f_rev",
						"VERSION_4_4",
					};
					for (auto it : gl440exts)
						m_extension_list[it] = true;
				}
				case 430:
				{
					std::string gl430exts[] = {
						"GL_ARB_ES3_compatibility",
						"GL_ARB_arrays_of_arrays",
						"GL_ARB_clear_buffer_object",
						"GL_ARB_compute_shader",
						"GL_ARB_copy_image",
						"GL_ARB_explicit_uniform_location",
						"GL_ARB_fragment_layer_viewport",
						"GL_ARB_framebuffer_no_attachments",
						"GL_ARB_internalformat_query2",
						"GL_ARB_invalidate_subdata",
						"GL_ARB_multi_draw_indirect",
						"GL_ARB_program_interface_query",
						"GL_ARB_shader_image_size",
						"GL_ARB_shader_storage_buffer_object",
						"GL_ARB_stencil_texturing",
						"GL_ARB_texture_buffer_range",
						"GL_ARB_texture_query_levels",
						"GL_ARB_texture_storage_multisample",
						"GL_ARB_texture_view",
						"GL_ARB_vertex_attrib_binding",
						"VERSION_4_3",
					};
					for (auto it : gl430exts)
						m_extension_list[it] = true;
				}
				case 420:
				{
					std::string gl420exts[] = {
						"GL_ARB_base_instance",
						"GL_ARB_compressed_texture_pixel_storage",
						"GL_ARB_conservative_depth",
						"GL_ARB_internalformat_query",
						"GL_ARB_map_buffer_alignment",
						"GL_ARB_shader_atomic_counters",
						"GL_ARB_shader_image_load_store",
						"GL_ARB_shading_language_420pack",
						"GL_ARB_shading_language_packing",
						"GL_ARB_texture_compression_BPTC",
						"GL_ARB_texture_storage",
						"GL_ARB_transform_feedback_instanced",
						"VERSION_4_2",
					};
					for (auto it : gl420exts)
						m_extension_list[it] = true;
				}
				case 410:
				{
					std::string gl410exts[] = {
						"GL_ARB_ES2_compatibility",
						"GL_ARB_get_program_binary",
						"GL_ARB_separate_shader_objects",
						"GL_ARB_shader_precision",
						"GL_ARB_vertex_attrib_64_bit",
						"GL_ARB_viewport_array",
						"VERSION_4_1",
					};
					for (auto it : gl410exts)
						m_extension_list[it] = true;
				}
				case 400:
				{
					std::string gl400exts[] = {
						"GL_ARB_draw_indirect",
						"GL_ARB_gpu_shader5",
						"GL_ARB_gpu_shader_fp64",
						"GL_ARB_sample_shading",
						"GL_ARB_shader_subroutine",
						"GL_ARB_tessellation_shader",
						"GL_ARB_texture_buffer_object_rgb32",
						"GL_ARB_texture_cube_map_array",
						"GL_ARB_texture_gather",
						"GL_ARB_texture_query_lod",
						"GL_ARB_transform_feedback2",
						"GL_ARB_transform_feedback3",
						"VERSION_4_0",
					};
					for (auto it : gl400exts)
						m_extension_list[it] = true;
				}
				case 330:
				{
					std::string gl330exts[] = {
						"GL_ARB_shader_bit_encoding",
						"GL_ARB_blend_func_extended",
						"GL_ARB_explicit_attrib_location",
						"GL_ARB_occlusion_query2",
						"GL_ARB_sampler_objects",
						"GL_ARB_texture_swizzle",
						"GL_ARB_timer_query",
						"GL_ARB_instanced_arrays",
						"GL_ARB_texture_rgb10_a2ui",
						"GL_ARB_vertex_type_2_10_10_10_rev",
						"VERSION_3_3",
					};
					for (auto it : gl330exts)
						m_extension_list[it] = true;
				}
				case 320:
				{
					std::string gl320exts[] = {
						"GL_ARB_geometry_shader4",
						"GL_ARB_sync",
						"GL_ARB_vertex_array_bgra",
						"GL_ARB_draw_elements_base_vertex",
						"GL_ARB_seamless_cube_map",
						"GL_ARB_texture_multisample",
						"GL_ARB_fragment_coord_conventions",
						"GL_ARB_provoking_vertex",
						"GL_ARB_depth_clamp",
						"VERSION_3_2",
					};
					for (auto it : gl320exts)
						m_extension_list[it] = true;
				}
				case 310:
				{
					// Can't add NV_primitive_restart since function name changed
					std::string gl310exts[] = {
						"GL_ARB_draw_instanced",
						"GL_ARB_copy_buffer",
						"GL_ARB_texture_buffer_object",
						"GL_ARB_texture_rectangle",
						"GL_ARB_uniform_buffer_object",
						//"GL_NV_primitive_restart",
						"VERSION_3_1",
					};
					for (auto it : gl310exts)
						m_extension_list[it] = true;
				}
				case 300:
				{
					// Quite a lot of these had their names changed when merged in to core
					// Disable the ones that have
					std::string gl300exts[] = {
						"GL_ARB_map_buffer_range",
						//"GL_EXT_gpu_shader4",
						//"GL_APPLE_flush_buffer_range",
						"GL_ARB_color_buffer_float",
						//"GL_NV_depth_buffer_float",
						"GL_ARB_texture_float",
						//"GL_EXT_packed_float",
						//"GL_EXT_texture_shared_exponent",
						"GL_ARB_half_float_pixel",
						//"GL_NV_half_float",
						"GL_ARB_framebuffer_object",
						//"GL_EXT_framebuffer_sRGB",
						"GL_ARB_texture_float",
						//"GL_EXT_texture_integer",
						//"GL_EXT_draw_buffers2",
						//"GL_EXT_texture_integer",
						//"GL_EXT_texture_array",
						//"GL_EXT_texture_compression_rgtc",
						//"GL_EXT_transform_feedback",
						"GL_ARB_vertex_array_object",
						//"GL_NV_conditional_render",
						"VERSION_3_0",
					};
					for (auto it : gl300exts)
						m_extension_list[it] = true;
				}
				case 210:
				case 200:
				case 150:
				case 140:
				case 130:
				case 121:
				case 120:
				case 110:
				case 100:
				break;
			}
			// So we can easily determine if we are running dekstop GL
			m_extension_list["VERSION_GL"] = true;
		}

		if (_GLVersion < 300)
		{
			InitExtensionList21();
			return;
		}
		GLint NumExtension = 0;
		glGetIntegerv(GL_NUM_EXTENSIONS, &NumExtension);
		for (GLint i = 0; i < NumExtension; ++i)
			m_extension_list[std::string((const char*)glGetStringi(GL_EXTENSIONS, i))] = true;
	}
	static void InitVersion()
	{
		GLint major, minor;
		glGetIntegerv(GL_MAJOR_VERSION, &major);
		glGetIntegerv(GL_MINOR_VERSION, &minor);
		if (glGetError() == GL_NO_ERROR)
			_GLVersion = major * 100 + minor * 10;
		else
			_GLVersion = 210;
	}

	static void* GetFuncAddress(const std::string& name, void **func)
	{
		*func = GLInterface->GetFuncAddress(name);
		if (*func == nullptr)
		{
#if defined(__linux__) || defined(__APPLE__)
			// Give it a second try with dlsym
			*func = dlsym(RTLD_NEXT, name.c_str());
#endif
			if (*func == nullptr)
				ERROR_LOG(VIDEO, "Couldn't load function %s", name.c_str());
		}
		return *func;
	}

	// Public members
	u32 Version() { return _GLVersion; }
	bool Supports(const std::string& name)
	{
		return m_extension_list[name];
	}

	bool Init()
	{
		_isES = GLInterface->GetMode() != GLInterfaceMode::MODE_OPENGL;

		// Grab a few functions for initial checking
		// We need them to grab the extension list
		// Also to check if there is an error grabbing the version
		if (GetFuncAddress("glGetIntegerv", (void**)&glGetIntegerv) == nullptr)
			return false;
		if (GetFuncAddress("glGetString", (void**)&glGetString) == nullptr)
			return false;
		if (GetFuncAddress("glGetError", (void**)&glGetError) == nullptr)
			return false;

		InitVersion();

		// We need to use glGetStringi to get the extension list
		// if we are using GLES3 or a GL version greater than 2.1
		if (_GLVersion > 210 && GetFuncAddress("glGetStringi", (void**)&glGetStringi) == nullptr)
			return false;

		InitExtensionList();

		return InitFunctionPointers();
	}

	// Private initialization functions
	static bool HasFeatures(const std::string& extensions)
	{
		bool result = true;
		std::string tmp;
		std::istringstream buffer(extensions);

		while (buffer >> tmp)
		{
			if (tmp[0] == '!')
				result &= !m_extension_list[tmp.erase(0, 1)];
			else if (tmp[0] == '|')
				result |= m_extension_list[tmp.erase(0, 1)];
			else
				result &= m_extension_list[tmp];
		}
		return result;
	}
	bool InitFunctionPointers()
	{
		bool result = true;
		for (const auto &it : gl_function_array)
			if (HasFeatures(it.requirements))
				result &= !!GetFuncAddress(it.function_name, it.function_ptr);
		return result;
	}
}

