// Copyright (C) 2012 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #include #include #include namespace { #ifdef NAZARA_PLATFORM_WINDOWS HMODULE openGLlibrary; #endif NzOpenGLFunc LoadEntry(const char* name, bool launchException = true) { #if defined(NAZARA_PLATFORM_WINDOWS) NzOpenGLFunc entry = reinterpret_cast(wglGetProcAddress(name)); if (!entry) // wglGetProcAddress ne fonctionne pas sur les fonctions OpenGL <= 1.1 entry = reinterpret_cast(GetProcAddress(openGLlibrary, name)); #elif defined(NAZARA_PLATFORM_LINUX) NzOpenGLFunc entry = reinterpret_cast(glXGetProcAddress(name)); #else #error OS not handled #endif if (!entry && launchException) { std::ostringstream oss; oss << "failed to load \"" << name << '"'; throw std::runtime_error(oss.str()); } return entry; } bool LoadLibrary() { #ifdef NAZARA_PLATFORM_WINDOWS openGLlibrary = ::LoadLibraryA("opengl32.dll"); return openGLlibrary != nullptr; #else return true; #endif } void UnloadLibrary() { #ifdef NAZARA_PLATFORM_WINDOWS FreeLibrary(openGLlibrary); #endif } std::set openGLextensionSet; bool openGLextensions[NzOpenGL::Max+1] = {false}; unsigned int openGLversion = 0; bool LoadExtensionsString(const NzString& extensionString) { if (extensionString.IsEmpty()) { NazaraError("Unable to get extension string"); return false; } // On peut sûrement faire plus rapide mais comme ça ne se fait qu'une fois et que NzString implémente le COW... std::vector ext; extensionString.Split(ext); for (std::vector::iterator it = ext.begin(); it != ext.end(); ++it) openGLextensionSet.insert(*it); return true; } bool LoadExtensions3() { GLint extensionCount = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); if (extensionCount <= 0) { NazaraError("Unable to get extension count"); return false; } for (int i = 0; i < extensionCount; ++i) { NzString extension(reinterpret_cast(glGetStringi(GL_EXTENSIONS, i))); if (extension.IsEmpty()) { NazaraWarning("Unable to get extension #" + NzString::Number(i)); continue; } openGLextensionSet.insert(extension); } return true; } } NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint) { return LoadEntry(entryPoint.GetConstBuffer(), false); } unsigned int NzOpenGL::GetVersion() { return openGLversion; } bool NzOpenGL::Initialize() { if (!LoadLibrary()) { NazaraError("Failed to load OpenGL library"); return false; } // Le chargement des fonctions OpenGL nécessite un contexte OpenGL NzContextParameters parameters; parameters.majorVersion = 2; parameters.minorVersion = 0; parameters.shared = false; /* Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser Pour cette raison, deux contextes sont créés, le premier sert à récupérer les fonctions permetttant de créer le second avec les bons paramètres. Non sérieusement si quelqu'un a une meilleure idée qu'il me le dise */ /****************************************Initialisation****************************************/ NzContext loadContext; if (!loadContext.Create(parameters)) { NazaraError("Failed to create load context"); Uninitialize(); return false; } #if defined(NAZARA_PLATFORM_WINDOWS) wglCreateContextAttribs = reinterpret_cast(LoadEntry("wglCreateContextAttribsARB", false)); wglChoosePixelFormat = reinterpret_cast(LoadEntry("wglChoosePixelFormatARB", false)); if (!wglChoosePixelFormat) wglChoosePixelFormat = reinterpret_cast(LoadEntry("wglChoosePixelFormatEXT", false)); #elif defined(NAZARA_PLATFORM_LINUX) glXCreateContextAttribs = reinterpret_cast(LoadEntry("glXCreateContextAttribsARB", false)); #endif // Récupération de la version d'OpenGL // Ce code se base sur le fait que la carte graphique renverra un contexte de compatibilité avec la plus haute version supportée // Ce qui semble vrai au moins chez ATI/AMD et NVidia, mais si quelqu'un à une meilleure idée ... glGetString = reinterpret_cast(LoadEntry("glGetString", false)); if (!glGetString) { NazaraError("Unable to load OpenGL: failed to load glGetString"); Uninitialize(); return false; } const GLubyte* version = glGetString(GL_VERSION); if (!version) { NazaraError("Unable to retrieve OpenGL version"); Uninitialize(); return false; } unsigned int major = version[0] - '0'; unsigned int minor = version[2] - '0'; if (major == 0 || major > 9) { NazaraError("Unable to retrieve OpenGL major version"); return false; } if (minor > 9) { NazaraWarning("Unable to retrieve OpenGL minor version (using 0)"); minor = 0; } openGLversion = major*100 + minor*10; if (openGLversion < 200) { NazaraError("OpenGL version is too low, please upgrade your drivers or your graphics card"); Uninitialize(); return false; } parameters.debugMode = true; // Certaines extensions n'apparaissent qu'avec un contexte de debug (e.g. ARB_debug_output) parameters.majorVersion = NzContextParameters::defaultMajorVersion = major; parameters.minorVersion = NzContextParameters::defaultMinorVersion = minor; // Destruction implicite du premier contexte if (!loadContext.Create(parameters)) { NazaraError("Failed to create load context"); Uninitialize(); return false; } /****************************************Noyau****************************************/ try { glActiveTexture = reinterpret_cast(LoadEntry("glActiveTexture")); glAttachShader = reinterpret_cast(LoadEntry("glAttachShader")); glBeginQuery = reinterpret_cast(LoadEntry("glBeginQuery")); glBindAttribLocation = reinterpret_cast(LoadEntry("glBindAttribLocation")); glBindBuffer = reinterpret_cast(LoadEntry("glBindBuffer")); glBindTexture = reinterpret_cast(LoadEntry("glBindTexture")); glBlendFunc = reinterpret_cast(LoadEntry("glBlendFunc")); glBufferData = reinterpret_cast(LoadEntry("glBufferData")); glBufferSubData = reinterpret_cast(LoadEntry("glBufferSubData")); glClear = reinterpret_cast(LoadEntry("glClear")); glClearColor = reinterpret_cast(LoadEntry("glClearColor")); glClearDepth = reinterpret_cast(LoadEntry("glClearDepth")); glClearStencil = reinterpret_cast(LoadEntry("glClearStencil")); glCreateProgram = reinterpret_cast(LoadEntry("glCreateProgram")); glCreateShader = reinterpret_cast(LoadEntry("glCreateShader")); glColorMask = reinterpret_cast(LoadEntry("glColorMask")); glCullFace = reinterpret_cast(LoadEntry("glCullFace")); glCompileShader = reinterpret_cast(LoadEntry("glCompileShader")); glCopyTexSubImage2D = reinterpret_cast(LoadEntry("glCopyTexSubImage2D")); glDeleteBuffers = reinterpret_cast(LoadEntry("glDeleteBuffers")); glDeleteQueries = reinterpret_cast(LoadEntry("glDeleteQueries")); glDeleteProgram = reinterpret_cast(LoadEntry("glDeleteProgram")); glDeleteShader = reinterpret_cast(LoadEntry("glDeleteShader")); glDeleteTextures = reinterpret_cast(LoadEntry("glDeleteTextures")); glDepthFunc = reinterpret_cast(LoadEntry("glDepthFunc")); glDepthMask = reinterpret_cast(LoadEntry("glDepthMask")); glDisable = reinterpret_cast(LoadEntry("glDisable")); glDisableVertexAttribArray = reinterpret_cast(LoadEntry("glDisableVertexAttribArray")); glDrawArrays = reinterpret_cast(LoadEntry("glDrawArrays")); glDrawBuffer = reinterpret_cast(LoadEntry("glDrawBuffer")); glDrawBuffers = reinterpret_cast(LoadEntry("glDrawBuffers")); glDrawElements = reinterpret_cast(LoadEntry("glDrawElements")); glFlush = reinterpret_cast(LoadEntry("glFlush")); glEnable = reinterpret_cast(LoadEntry("glEnable")); glEnableVertexAttribArray = reinterpret_cast(LoadEntry("glEnableVertexAttribArray")); glEndQuery = reinterpret_cast(LoadEntry("glEndQuery")); glGenBuffers = reinterpret_cast(LoadEntry("glGenBuffers")); glGenQueries = reinterpret_cast(LoadEntry("glGenQueries")); glGenTextures = reinterpret_cast(LoadEntry("glGenTextures")); glGetBufferParameteriv = reinterpret_cast(LoadEntry("glGetBufferParameteriv")); glGetError = reinterpret_cast(LoadEntry("glGetError")); glGetQueryiv = reinterpret_cast(LoadEntry("glGetQueryiv")); glGetQueryObjectiv = reinterpret_cast(LoadEntry("glGetQueryObjectiv")); glGetQueryObjectuiv = reinterpret_cast(LoadEntry("glGetQueryObjectuiv")); glGetIntegerv = reinterpret_cast(LoadEntry("glGetIntegerv")); glGetProgramiv = reinterpret_cast(LoadEntry("glGetProgramiv")); glGetProgramInfoLog = reinterpret_cast(LoadEntry("glGetProgramInfoLog")); glGetShaderInfoLog = reinterpret_cast(LoadEntry("glGetShaderInfoLog")); glGetShaderiv = reinterpret_cast(LoadEntry("glGetShaderiv")); glGetShaderSource = reinterpret_cast(LoadEntry("glGetShaderSource")); glGetTexImage = reinterpret_cast(LoadEntry("glGetTexImage")); glGetTexLevelParameterfv = reinterpret_cast(LoadEntry("glGetTexLevelParameterfv")); glGetTexLevelParameteriv = reinterpret_cast(LoadEntry("glGetTexLevelParameteriv")); glGetTexParameterfv = reinterpret_cast(LoadEntry("glGetTexParameterfv")); glGetTexParameteriv = reinterpret_cast(LoadEntry("glGetTexParameteriv")); glGetUniformLocation = reinterpret_cast(LoadEntry("glGetUniformLocation")); glLinkProgram = reinterpret_cast(LoadEntry("glLinkProgram")); glMapBuffer = reinterpret_cast(LoadEntry("glMapBuffer")); glPixelStorei = reinterpret_cast(LoadEntry("glPixelStorei")); glPolygonMode = reinterpret_cast(LoadEntry("glPolygonMode")); glReadPixels = reinterpret_cast(LoadEntry("glReadPixels")); glScissor = reinterpret_cast(LoadEntry("glScissor")); glShaderSource = reinterpret_cast(LoadEntry("glShaderSource")); glStencilFunc = reinterpret_cast(LoadEntry("glStencilFunc")); glStencilOp = reinterpret_cast(LoadEntry("glStencilOp")); glTexImage2D = reinterpret_cast(LoadEntry("glTexImage2D")); glTexParameterf = reinterpret_cast(LoadEntry("glTexParameterf")); glTexParameteri = reinterpret_cast(LoadEntry("glTexParameteri")); glTexSubImage2D = reinterpret_cast(LoadEntry("glTexSubImage2D")); glUniform1f = reinterpret_cast(LoadEntry("glUniform1f")); glUniform1i = reinterpret_cast(LoadEntry("glUniform1i")); glUniform2fv = reinterpret_cast(LoadEntry("glUniform2fv")); glUniform3fv = reinterpret_cast(LoadEntry("glUniform3fv")); glUniform4fv = reinterpret_cast(LoadEntry("glUniform4fv")); glUniformMatrix4fv = reinterpret_cast(LoadEntry("glUniformMatrix4fv")); glUnmapBuffer = reinterpret_cast(LoadEntry("glUnmapBuffer")); glUseProgram = reinterpret_cast(LoadEntry("glUseProgram")); glVertexAttrib4f = reinterpret_cast(LoadEntry("glVertexAttrib4f")); glVertexAttribPointer = reinterpret_cast(LoadEntry("glVertexAttribPointer")); glViewport = reinterpret_cast(LoadEntry("glViewport")); } catch (const std::exception& e) { NazaraError("Unable to load OpenGL: " + NzString(e.what())); Uninitialize(); return false; } /****************************************Extensions****************************************/ glGetStringi = reinterpret_cast(LoadEntry("glGetStringi", false)); glMapBufferRange = reinterpret_cast(LoadEntry("glMapBufferRange", false)); #if defined(NAZARA_PLATFORM_WINDOWS) wglGetExtensionsStringARB = reinterpret_cast(LoadEntry("wglGetExtensionsStringARB", false)); wglGetExtensionsStringEXT = reinterpret_cast(LoadEntry("wglGetExtensionsStringEXT", false)); wglSwapInterval = reinterpret_cast(LoadEntry("wglSwapIntervalEXT", false)); #elif defined(NAZARA_PLATFORM_LINUX) glXSwapInterval = reinterpret_cast(LoadEntry("glXSwapIntervalSGI", false)); #endif if (!glGetStringi || !LoadExtensions3()) { if (openGLversion >= 300) // Dans le cas contraire c'est normal NazaraWarning("Failed to load OpenGL 3 extension system, switching to OpenGL 2 extension system..."); if (!LoadExtensionsString(reinterpret_cast(glGetString(GL_EXTENSIONS)))) NazaraWarning("Failed to load extension system"); } #ifdef NAZARA_PLATFORM_WINDOWS { bool loaded; if (wglGetExtensionsStringARB) loaded = LoadExtensionsString(reinterpret_cast(wglGetExtensionsStringARB(wglGetCurrentDC()))); else if (wglGetExtensionsStringEXT) loaded = LoadExtensionsString(reinterpret_cast(wglGetExtensionsStringEXT())); else loaded = false; if (!loaded) NazaraWarning("Failed to load wgl extension string"); } #endif // AnisotropicFilter openGLextensions[NzOpenGL::AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic"); // DebugOutput if (openGLversion >= 430 || IsSupported("GL_KHR_debug")) { try { glDebugMessageCallback = reinterpret_cast(LoadEntry("glDebugMessageCallback")); glDebugMessageControl = reinterpret_cast(LoadEntry("glDebugMessageControl")); glDebugMessageInsert = reinterpret_cast(LoadEntry("glDebugMessageInsert")); glGetDebugMessageLog = reinterpret_cast(LoadEntry("glGetDebugMessageLog")); openGLextensions[NzOpenGL::DebugOutput] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load GL_KHR_debug: " + NzString(e.what())); } } if (!openGLextensions[NzOpenGL::DebugOutput] && IsSupported("GL_ARB_debug_output")) { try { glDebugMessageCallback = reinterpret_cast(LoadEntry("glDebugMessageCallbackARB")); glDebugMessageControl = reinterpret_cast(LoadEntry("glDebugMessageControlARB")); glDebugMessageInsert = reinterpret_cast(LoadEntry("glDebugMessageInsertARB")); glGetDebugMessageLog = reinterpret_cast(LoadEntry("glGetDebugMessageLogARB")); openGLextensions[NzOpenGL::DebugOutput] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load GL_ARB_debug_output: " + NzString(e.what())); } } // FP64 if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64")) { try { glUniform1d = reinterpret_cast(LoadEntry("glUniform1d")); glUniform2dv = reinterpret_cast(LoadEntry("glUniform2dv")); glUniform3dv = reinterpret_cast(LoadEntry("glUniform3dv")); glUniform4dv = reinterpret_cast(LoadEntry("glUniform4dv")); openGLextensions[NzOpenGL::FP64] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load ARB_gpu_shader_fp64: " + NzString(e.what())); } } // FrameBufferObject if (openGLversion >= 300 || IsSupported("GL_ARB_framebuffer_object")) { try { glBindFramebuffer = reinterpret_cast(LoadEntry("glBindFramebuffer")); glBindRenderbuffer = reinterpret_cast(LoadEntry("glBindRenderbuffer")); glCheckFramebufferStatus = reinterpret_cast(LoadEntry("glCheckFramebufferStatus")); glDeleteFramebuffers = reinterpret_cast(LoadEntry("glDeleteFramebuffers")); glDeleteRenderbuffers = reinterpret_cast(LoadEntry("glDeleteRenderbuffers")); glFramebufferRenderbuffer = reinterpret_cast(LoadEntry("glFramebufferRenderbuffer")); glFramebufferTexture2D = reinterpret_cast(LoadEntry("glFramebufferTexture2D")); glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmap")); glGenFramebuffers = reinterpret_cast(LoadEntry("glGenFramebuffers")); glGenRenderbuffers = reinterpret_cast(LoadEntry("glGenRenderbuffers")); glRenderbufferStorage = reinterpret_cast(LoadEntry("glRenderbufferStorage")); openGLextensions[NzOpenGL::FrameBufferObject] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")"); } } // PixelBufferObject openGLextensions[NzOpenGL::PixelBufferObject] = (openGLversion >= 210 || IsSupported("GL_ARB_pixel_buffer_object")); // SeparateShaderObjects if (openGLversion >= 400 || IsSupported("GL_ARB_separate_shader_objects")) { glProgramUniform1f = reinterpret_cast(LoadEntry("glProgramUniform1f")); glProgramUniform1i = reinterpret_cast(LoadEntry("glProgramUniform1i")); glProgramUniform2fv = reinterpret_cast(LoadEntry("glProgramUniform2fv")); glProgramUniform3fv = reinterpret_cast(LoadEntry("glProgramUniform3fv")); glProgramUniform4fv = reinterpret_cast(LoadEntry("glProgramUniform4fv")); glProgramUniformMatrix4fv = reinterpret_cast(LoadEntry("glProgramUniformMatrix4fv")); // Si ARB_gpu_shader_fp64 est supporté, alors cette extension donne également accès aux fonctions utilisant des double if (openGLextensions[NzOpenGL::FP64]) { glProgramUniform1d = reinterpret_cast(LoadEntry("glProgramUniform1d")); glProgramUniform2dv = reinterpret_cast(LoadEntry("glProgramUniform2dv")); glProgramUniform3dv = reinterpret_cast(LoadEntry("glProgramUniform3dv")); glProgramUniform4dv = reinterpret_cast(LoadEntry("glProgramUniform4dv")); glProgramUniformMatrix4dv = reinterpret_cast(LoadEntry("glProgramUniformMatrix4dv")); } openGLextensions[NzOpenGL::SeparateShaderObjects] = true; } // Texture3D try { glTexImage3D = reinterpret_cast(LoadEntry("glTexImage3D")); glTexSubImage3D = reinterpret_cast(LoadEntry("glTexSubImage3D")); openGLextensions[NzOpenGL::Texture3D] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load core texture 3D (" + NzString(e.what()) + ")"); if (IsSupported("GL_EXT_texture3D")) { try { // Hacky: Normalement incompatible à cause du internalFormat, GLenum pour l'extension et GLint pour le noyau // Mais la taille du type étant la même (GLenum est un typedef équivalent à GLint) et Nazara n'utilisant pas // Ce qui cause l'incompatibilité (les paramètres 1,2,3,4), je prends cette liberté glTexImage3D = reinterpret_cast(LoadEntry("glTexImage3DEXT")); glTexSubImage3D = reinterpret_cast(LoadEntry("glTexSubImage3DEXT")); openGLextensions[NzOpenGL::Texture3D] = true; } catch (const std::exception& e2) { NazaraWarning("Failed to load EXT_texture3D: " + NzString(e2.what())); } } } // TextureArray openGLextensions[NzOpenGL::TextureArray] = (openGLversion >= 300 || IsSupported("GL_EXT_texture_array")); // TextureCompression_s3tc openGLextensions[NzOpenGL::TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc"); // TextureStorage if (openGLversion >= 420 || IsSupported("GL_ARB_texture_storage")) { try { glTexStorage1D = reinterpret_cast(LoadEntry("glTexStorage1D")); glTexStorage2D = reinterpret_cast(LoadEntry("glTexStorage2D")); glTexStorage3D = reinterpret_cast(LoadEntry("glTexStorage3D")); openGLextensions[NzOpenGL::TextureStorage] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load ARB_texture_storage: " + NzString(e.what())); } } // VertexArrayObject if (openGLversion >= 300 || IsSupported("GL_ARB_vertex_array_object")) { try { glBindVertexArray = reinterpret_cast(LoadEntry("glBindVertexArray")); glDeleteVertexArrays = reinterpret_cast(LoadEntry("glDeleteVertexArrays")); glGenVertexArrays = reinterpret_cast(LoadEntry("glGenVertexArrays")); openGLextensions[NzOpenGL::VertexArrayObject] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load ARB_vertex_array_object: " + NzString(e.what())); } } // Fonctions de substitut if (!glGenerateMipmap) glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmapEXT", false)); /****************************************Contexte de référence****************************************/ ///FIXME: Utiliser le contexte de chargement comme référence ? (Vérifier mode debug) if (!NzContext::Initialize()) { NazaraError("Failed to initialize contexts"); Uninitialize(); return false; } NzContextParameters::defaultShareContext = NzContext::GetReference(); return true; } bool NzOpenGL::IsSupported(Extension extension) { return openGLextensions[extension]; } bool NzOpenGL::IsSupported(const NzString& string) { return openGLextensionSet.find(string) != openGLextensionSet.end(); } void NzOpenGL::Uninitialize() { NzContext::Uninitialize(); for (bool& ext : openGLextensions) ext = false; openGLextensionSet.clear(); openGLversion = 0; UnloadLibrary(); } PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr; PFNGLATTACHSHADERPROC glAttachShader = nullptr; PFNGLBEGINQUERYPROC glBeginQuery = nullptr; PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = nullptr; PFNGLBINDBUFFERPROC glBindBuffer = nullptr; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr; PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = nullptr; PFNGLBINDTEXTUREPROC glBindTexture = nullptr; PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr; PFNGLBLENDFUNCPROC glBlendFunc = nullptr; PFNGLBUFFERDATAPROC glBufferData = nullptr; PFNGLBUFFERSUBDATAPROC glBufferSubData = nullptr; PFNGLCLEARPROC glClear = nullptr; PFNGLCLEARCOLORPROC glClearColor = nullptr; PFNGLCLEARDEPTHPROC glClearDepth = nullptr; PFNGLCLEARSTENCILPROC glClearStencil = nullptr; PFNGLCREATEPROGRAMPROC glCreateProgram = nullptr; PFNGLCREATESHADERPROC glCreateShader = nullptr; PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = nullptr; PFNGLCOLORMASKPROC glColorMask = nullptr; PFNGLCULLFACEPROC glCullFace = nullptr; PFNGLCOMPILESHADERPROC glCompileShader = nullptr; PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D = nullptr; PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback = nullptr; PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl = nullptr; PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert = nullptr; PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr; PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr; PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr; PFNGLDELETEQUERIESPROC glDeleteQueries = nullptr; PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = nullptr; PFNGLDELETESHADERPROC glDeleteShader = nullptr; PFNGLDELETETEXTURESPROC glDeleteTextures = nullptr; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = nullptr; PFNGLDEPTHFUNCPROC glDepthFunc = nullptr; PFNGLDEPTHMASKPROC glDepthMask = nullptr; PFNGLDISABLEPROC glDisable = nullptr; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = nullptr; PFNGLDRAWARRAYSPROC glDrawArrays = nullptr; PFNGLDRAWBUFFERPROC glDrawBuffer = nullptr; PFNGLDRAWBUFFERSPROC glDrawBuffers = nullptr; PFNGLDRAWELEMENTSPROC glDrawElements = nullptr; PFNGLENDQUERYPROC glEndQuery = nullptr; PFNGLFLUSHPROC glFlush = nullptr; PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = nullptr; PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = nullptr; PFNGLENABLEPROC glEnable = nullptr; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = nullptr; PFNGLGENERATEMIPMAPPROC glGenerateMipmap = nullptr; PFNGLGENBUFFERSPROC glGenBuffers = nullptr; PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = nullptr; PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = nullptr; PFNGLGENQUERIESPROC glGenQueries = nullptr; PFNGLGENTEXTURESPROC glGenTextures = nullptr; PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr; PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr; PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog = nullptr; PFNGLGETERRORPROC glGetError = nullptr; PFNGLGETINTEGERVPROC glGetIntegerv = nullptr; PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr; PFNGLGETQUERYIVPROC glGetQueryiv = nullptr; PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv = nullptr; PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv = nullptr; PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = nullptr; PFNGLGETSHADERIVPROC glGetShaderiv = nullptr; PFNGLGETSHADERSOURCEPROC glGetShaderSource = nullptr; PFNGLGETSTRINGPROC glGetString = nullptr; PFNGLGETSTRINGIPROC glGetStringi = nullptr; PFNGLGETTEXIMAGEPROC glGetTexImage = nullptr; PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv = nullptr; PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv = nullptr; PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv = nullptr; PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv = nullptr; PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr; PFNGLLINKPROGRAMPROC glLinkProgram = nullptr; PFNGLMAPBUFFERPROC glMapBuffer = nullptr; PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr; PFNGLPIXELSTOREIPROC glPixelStorei = nullptr; PFNGLPOLYGONMODEPROC glPolygonMode = nullptr; PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr; PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr; PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = nullptr; PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv = nullptr; PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv = nullptr; PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv = nullptr; PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv = nullptr; PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv = nullptr; PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv = nullptr; PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv = nullptr; PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv = nullptr; PFNGLREADPIXELSPROC glReadPixels = nullptr; PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = nullptr; PFNGLSCISSORPROC glScissor = nullptr; PFNGLSHADERSOURCEPROC glShaderSource = nullptr; PFNGLSTENCILFUNCPROC glStencilFunc = nullptr; PFNGLSTENCILOPPROC glStencilOp = nullptr; PFNGLTEXIMAGE1DPROC glTexImage1D = nullptr; PFNGLTEXIMAGE2DPROC glTexImage2D = nullptr; PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr; PFNGLTEXPARAMETERFPROC glTexParameterf = nullptr; PFNGLTEXPARAMETERIPROC glTexParameteri = nullptr; PFNGLTEXSTORAGE1DPROC glTexStorage1D = nullptr; PFNGLTEXSTORAGE2DPROC glTexStorage2D = nullptr; PFNGLTEXSTORAGE3DPROC glTexStorage3D = nullptr; PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D = nullptr; PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D = nullptr; PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr; PFNGLUNIFORM1DPROC glUniform1d = nullptr; PFNGLUNIFORM1FPROC glUniform1f = nullptr; PFNGLUNIFORM1IPROC glUniform1i = nullptr; PFNGLUNIFORM2DVPROC glUniform2dv = nullptr; PFNGLUNIFORM2FVPROC glUniform2fv = nullptr; PFNGLUNIFORM3DVPROC glUniform3dv = nullptr; PFNGLUNIFORM3FVPROC glUniform3fv = nullptr; PFNGLUNIFORM4DVPROC glUniform4dv = nullptr; PFNGLUNIFORM4FVPROC glUniform4fv = nullptr; PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv = nullptr; PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = nullptr; PFNGLUNMAPBUFFERPROC glUnmapBuffer = nullptr; PFNGLUSEPROGRAMPROC glUseProgram = nullptr; PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = nullptr; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr; PFNGLVIEWPORTPROC glViewport = nullptr; #if defined(NAZARA_PLATFORM_WINDOWS) PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat = nullptr; PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr; PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = nullptr; PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT = nullptr; PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = nullptr; #elif defined(NAZARA_PLATFORM_LINUX) PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = nullptr; PFNGLXSWAPINTERVALSGIPROC glXSwapInterval = nullptr; #endif