//-----------------------------------------------------------------------------------------------
// OpenGLExtensions.cpp
//
// Handles dynamic loading of any functions not automatically available to us at compile-time.
//-----------------------------------------------------------------------------------------------
#include "GypsyPrecompiledHeader.hpp"
#include "Engine/Renderer/OpenGLExtensions.hpp"


//-----------------------------------------------------------------------------------------------
// Global OpenGL function pointers
//
PFNGLACTIVETEXTUREPROC				glActiveTexture				= nullptr;
PFNGLATTACHSHADERPROC				glAttachShader				= nullptr;
PFNGLBINDATTRIBLOCATIONPROC			glBindAttribLocation		= nullptr;
PFNGLBINDBUFFERPROC					glBindBuffer				= nullptr;
PFNGLBINDFRAMEBUFFERPROC			glBindFramebuffer			= nullptr;
PFNGLBUFFERDATAPROC					glBufferData				= nullptr;
PFNGLCOMPILESHADERPROC				glCompileShader				= nullptr;
PFNGLCREATEPROGRAMPROC				glCreateProgram				= nullptr;
PFNGLCREATESHADERPROC				glCreateShader				= nullptr;
PFNGLDELETEBUFFERSPROC				glDeleteBuffers				= nullptr;
PFNGLDISABLEVERTEXATTRIBARRAYPROC	glDisableVertexAttribArray	= nullptr;
PFNGLENABLEVERTEXATTRIBARRAYPROC	glEnableVertexAttribArray	= nullptr;
PFNGLFRAMEBUFFERTEXTURE2DPROC		glFramebufferTexture2D		= nullptr;
PFNGLGENBUFFERSPROC					glGenBuffers				= nullptr;
PFNGLGENFRAMEBUFFERSPROC			glGenFramebuffers			= nullptr;
PFNGLGETATTRIBLOCATIONPROC			glGetAttribLocation			= nullptr;
PFNGLGETPROGRAMINFOLOGPROC			glGetProgramInfoLog			= nullptr;
PFNGLGETPROGRAMIVPROC				glGetProgramiv				= nullptr;
PFNGLGETSHADERINFOLOGPROC			glGetShaderInfoLog			= nullptr;
PFNGLGETSHADERIVPROC				glGetShaderiv				= nullptr;
PFNGLGETUNIFORMLOCATIONPROC			glGetUniformLocation		= nullptr;
PFNGLLINKPROGRAMPROC				glLinkProgram				= nullptr;
PFNGLSHADERSOURCEPROC				glShaderSource				= nullptr;
PFNGLUNIFORM1FPROC					glUniform1f					= nullptr;
PFNGLUNIFORM2FPROC					glUniform2f					= nullptr;
PFNGLUNIFORM3FPROC					glUniform3f					= nullptr;
PFNGLUNIFORM4FPROC					glUniform4f					= nullptr;
PFNGLUNIFORM1IPROC					glUniform1i					= nullptr;
PFNGLUNIFORM2IPROC					glUniform2i					= nullptr;
PFNGLUNIFORM3IPROC					glUniform3i					= nullptr;
PFNGLUNIFORM4IPROC					glUniform4i					= nullptr;
PFNGLUNIFORM1UIPROC					glUniform1ui				= nullptr;
PFNGLUNIFORM2UIPROC					glUniform2ui				= nullptr;
PFNGLUNIFORM3UIPROC					glUniform3ui				= nullptr;
PFNGLUNIFORM4UIPROC					glUniform4ui				= nullptr;
PFNGLUNIFORM1FVPROC					glUniform1fv				= nullptr;
PFNGLUNIFORM2FVPROC					glUniform2fv				= nullptr;
PFNGLUNIFORM3FVPROC					glUniform3fv				= nullptr;
PFNGLUNIFORM4FVPROC					glUniform4fv				= nullptr;
PFNGLUNIFORMMATRIX4FVPROC			glUniformMatrix4fv			= nullptr;
PFNGLUSEPROGRAMPROC					glUseProgram				= nullptr;
PFNGLVERTEXATTRIB1FPROC				glVertexAttrib1f			= nullptr;
PFNGLVERTEXATTRIB1FVPROC			glVertexAttrib1fv			= nullptr;
PFNGLVERTEXATTRIB2FPROC				glVertexAttrib2f			= nullptr;
PFNGLVERTEXATTRIB2FVPROC			glVertexAttrib2fv			= nullptr;
PFNGLVERTEXATTRIB3FPROC				glVertexAttrib3f			= nullptr;
PFNGLVERTEXATTRIB3FVPROC			glVertexAttrib3fv			= nullptr;
PFNGLVERTEXATTRIB4FPROC				glVertexAttrib4f			= nullptr;
PFNGLVERTEXATTRIB4FVPROC			glVertexAttrib4fv			= nullptr;
PFNGLVERTEXATTRIB4NUBVPROC			glVertexAttrib4Nubv			= nullptr;
PFNGLVERTEXATTRIB4UBVPROC			glVertexAttrib4ubv			= nullptr;
PFNGLVERTEXATTRIBPOINTERPROC		glVertexAttribPointer		= nullptr;


//-----------------------------------------------------------------------------------------------
void BindAdvancedOpenGLFunctionPointers()
{
	glActiveTexture				= (PFNGLACTIVETEXTUREPROC)				wglGetProcAddress( "glActiveTexture" );
	glAttachShader				= (PFNGLATTACHSHADERPROC)				wglGetProcAddress( "glAttachShader" );
	glBindAttribLocation		= (PFNGLBINDATTRIBLOCATIONPROC)			wglGetProcAddress( "glBindAttribLocation" );
	glBindBuffer				= (PFNGLBINDBUFFERPROC)					wglGetProcAddress( "glBindBuffer" );
	glBindFramebuffer			= (PFNGLBINDFRAMEBUFFERPROC)			wglGetProcAddress( "glBindFramebuffer" );
	glBufferData				= (PFNGLBUFFERDATAPROC)					wglGetProcAddress( "glBufferData" );
	glCompileShader				= (PFNGLCOMPILESHADERPROC)				wglGetProcAddress( "glCompileShader" );
	glCreateProgram				= (PFNGLCREATEPROGRAMPROC)				wglGetProcAddress( "glCreateProgram" );
	glCreateShader				= (PFNGLCREATESHADERPROC)				wglGetProcAddress( "glCreateShader" );
	glDeleteBuffers				= (PFNGLDELETEBUFFERSPROC)				wglGetProcAddress( "glDeleteBuffers" );
	glDisableVertexAttribArray	= (PFNGLDISABLEVERTEXATTRIBARRAYPROC)	wglGetProcAddress( "glDisableVertexAttribArray" );
	glEnableVertexAttribArray	= (PFNGLENABLEVERTEXATTRIBARRAYPROC)	wglGetProcAddress( "glEnableVertexAttribArray" );
	glFramebufferTexture2D		= (PFNGLFRAMEBUFFERTEXTURE2DPROC)		wglGetProcAddress( "glFramebufferTexture2D" );
	glGenBuffers				= (PFNGLGENBUFFERSPROC)					wglGetProcAddress( "glGenBuffers" );
	glGenFramebuffers			= (PFNGLGENFRAMEBUFFERSPROC)			wglGetProcAddress( "glGenFramebuffers" );
	glGetAttribLocation			= (PFNGLGETATTRIBLOCATIONPROC)			wglGetProcAddress( "glGetAttribLocation" );
	glGetProgramInfoLog			= (PFNGLGETPROGRAMINFOLOGPROC)			wglGetProcAddress( "glGetProgramInfoLog" );
	glGetProgramiv				= (PFNGLGETPROGRAMIVPROC)				wglGetProcAddress( "glGetProgramiv" );
	glGetShaderInfoLog			= (PFNGLGETSHADERINFOLOGPROC)			wglGetProcAddress( "glGetShaderInfoLog" );
	glGetShaderiv				= (PFNGLGETSHADERIVPROC)				wglGetProcAddress( "glGetShaderiv" );
	glGetUniformLocation		= (PFNGLGETUNIFORMLOCATIONPROC)			wglGetProcAddress( "glGetUniformLocation" );
	glLinkProgram				= (PFNGLLINKPROGRAMPROC)				wglGetProcAddress( "glLinkProgram" );
	glShaderSource				= (PFNGLSHADERSOURCEPROC)				wglGetProcAddress( "glShaderSource" );
	glUniform1f					= (PFNGLUNIFORM1FPROC)					wglGetProcAddress( "glUniform1f" );
	glUniform2f					= (PFNGLUNIFORM2FPROC)					wglGetProcAddress( "glUniform2f" );
	glUniform3f					= (PFNGLUNIFORM3FPROC)					wglGetProcAddress( "glUniform3f" );
	glUniform4f					= (PFNGLUNIFORM4FPROC)					wglGetProcAddress( "glUniform4f" );
	glUniform1i					= (PFNGLUNIFORM1IPROC)					wglGetProcAddress( "glUniform1i" );
	glUniform2i					= (PFNGLUNIFORM2IPROC)					wglGetProcAddress( "glUniform2i" );
	glUniform3i					= (PFNGLUNIFORM3IPROC)					wglGetProcAddress( "glUniform3i" );
	glUniform4i					= (PFNGLUNIFORM4IPROC)					wglGetProcAddress( "glUniform4i" );
	glUniform1ui				= (PFNGLUNIFORM1UIPROC)					wglGetProcAddress( "glUniform1ui" );
	glUniform2ui				= (PFNGLUNIFORM2UIPROC)					wglGetProcAddress( "glUniform2ui" );
	glUniform3ui				= (PFNGLUNIFORM3UIPROC)					wglGetProcAddress( "glUniform3ui" );
	glUniform4ui				= (PFNGLUNIFORM4UIPROC)					wglGetProcAddress( "glUniform4ui" );
	glUniform1fv				= (PFNGLUNIFORM1FVPROC)					wglGetProcAddress( "glUniform1fv" );
	glUniform2fv				= (PFNGLUNIFORM2FVPROC)					wglGetProcAddress( "glUniform2fv" );
	glUniform3fv				= (PFNGLUNIFORM3FVPROC)					wglGetProcAddress( "glUniform3fv" );
	glUniform4fv				= (PFNGLUNIFORM4FVPROC)					wglGetProcAddress( "glUniform4fv" );
	glUniformMatrix4fv			= (PFNGLUNIFORMMATRIX4FVPROC)			wglGetProcAddress( "glUniformMatrix4fv" );
	glUseProgram				= (PFNGLUSEPROGRAMPROC)					wglGetProcAddress( "glUseProgram" );
	glVertexAttrib1f			= (PFNGLVERTEXATTRIB1FPROC)				wglGetProcAddress( "glVertexAttrib1f" );
	glVertexAttrib1fv			= (PFNGLVERTEXATTRIB1FVPROC)			wglGetProcAddress( "glVertexAttrib1fv" );
	glVertexAttrib2f			= (PFNGLVERTEXATTRIB2FPROC)				wglGetProcAddress( "glVertexAttrib2f" );
	glVertexAttrib2fv			= (PFNGLVERTEXATTRIB2FVPROC)			wglGetProcAddress( "glVertexAttrib2fv" );
	glVertexAttrib3f			= (PFNGLVERTEXATTRIB3FPROC)				wglGetProcAddress( "glVertexAttrib3f" );
	glVertexAttrib3fv			= (PFNGLVERTEXATTRIB3FVPROC)			wglGetProcAddress( "glVertexAttrib3fv" );
	glVertexAttrib4f			= (PFNGLVERTEXATTRIB4FPROC)				wglGetProcAddress( "glVertexAttrib4f" );
	glVertexAttrib4fv			= (PFNGLVERTEXATTRIB4FVPROC)			wglGetProcAddress( "glVertexAttrib4fv" );
	glVertexAttrib4Nubv			= (PFNGLVERTEXATTRIB4NUBVPROC)			wglGetProcAddress( "glVertexAttrib4Nubv" );
	glVertexAttrib4ubv			= (PFNGLVERTEXATTRIB4UBVPROC)			wglGetProcAddress( "glVertexAttrib4ubv" );
	glVertexAttribPointer		= (PFNGLVERTEXATTRIBPOINTERPROC)		wglGetProcAddress( "glVertexAttribPointer" );
}

