// 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[nzOpenGLExtension_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; } } namespace NzOpenGL { NzOpenGLFunc GetEntry(const NzString& entryPoint) { return LoadEntry(entryPoint.GetConstBuffer(), false); } unsigned int GetVersion() { return openGLversion; } bool 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 video 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; if (!loadContext.Create(parameters)) // Destruction implicite du premier contexte { 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")); glGetFloatv = reinterpret_cast(LoadEntry("glGetFloatv")); glGetIntegerv = reinterpret_cast(LoadEntry("glGetIntegerv")); glGetQueryiv = reinterpret_cast(LoadEntry("glGetQueryiv")); glGetQueryObjectiv = reinterpret_cast(LoadEntry("glGetQueryObjectiv")); glGetQueryObjectuiv = reinterpret_cast(LoadEntry("glGetQueryObjectuiv")); 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")); glPointSize = reinterpret_cast(LoadEntry("glPointSize")); 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")); glTexImage3D = reinterpret_cast(LoadEntry("glTexImage3D")); glTexParameterf = reinterpret_cast(LoadEntry("glTexParameterf")); glTexParameteri = reinterpret_cast(LoadEntry("glTexParameteri")); glTexSubImage2D = reinterpret_cast(LoadEntry("glTexSubImage2D")); glTexSubImage3D = reinterpret_cast(LoadEntry("glTexSubImage3D")); 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****************************************/ // Fonctions optionnelles glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocation", false)); if (!glBindFragDataLocation) glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocationEXT", false)); 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[nzOpenGLExtension_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[nzOpenGLExtension_DebugOutput] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load GL_KHR_debug: " + NzString(e.what())); } } if (!openGLextensions[nzOpenGLExtension_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[nzOpenGLExtension_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[nzOpenGLExtension_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")); glFramebufferTexture = reinterpret_cast(LoadEntry("glFramebufferTexture")); glFramebufferTexture1D = reinterpret_cast(LoadEntry("glFramebufferTexture1D")); glFramebufferTexture2D = reinterpret_cast(LoadEntry("glFramebufferTexture2D")); glFramebufferTexture3D = reinterpret_cast(LoadEntry("glFramebufferTexture3D")); glFramebufferTextureLayer = reinterpret_cast(LoadEntry("glFramebufferTextureLayer")); glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmap")); glGenFramebuffers = reinterpret_cast(LoadEntry("glGenFramebuffers")); glGenRenderbuffers = reinterpret_cast(LoadEntry("glGenRenderbuffers")); glRenderbufferStorage = reinterpret_cast(LoadEntry("glRenderbufferStorage")); openGLextensions[nzOpenGLExtension_FrameBufferObject] = true; } catch (const std::exception& e) { NazaraWarning("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")"); } } // PixelBufferObject openGLextensions[nzOpenGLExtension_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[nzOpenGLExtension_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[nzOpenGLExtension_SeparateShaderObjects] = true; } // TextureArray openGLextensions[nzOpenGLExtension_TextureArray] = (openGLversion >= 300 || IsSupported("GL_EXT_texture_array")); // TextureCompression_s3tc openGLextensions[nzOpenGLExtension_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[nzOpenGLExtension_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[nzOpenGLExtension_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 IsSupported(nzOpenGLExtension extension) { return openGLextensions[extension]; } bool IsSupported(const NzString& string) { return openGLextensionSet.find(string) != openGLextensionSet.end(); } bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType type) { switch (pixelFormat) { case nzPixelFormat_BGR8: format->dataFormat = GL_BGR; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_RGB8; return true; case nzPixelFormat_BGRA8: format->dataFormat = GL_BGRA; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_RGBA8; return true; case nzPixelFormat_DXT1: format->dataFormat = GL_RGB; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; return true; case nzPixelFormat_DXT3: format->dataFormat = GL_RGBA; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; return true; case nzPixelFormat_DXT5: format->dataFormat = GL_RGBA; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; return true; case nzPixelFormat_L8: case nzPixelFormat_LA8: return false; case nzPixelFormat_RGB5A1: format->dataFormat = GL_RGBA; format->dataType = GL_UNSIGNED_SHORT_5_5_5_1; format->internalFormat = GL_RGB5_A1; return true; case nzPixelFormat_RGB8: format->dataFormat = GL_RGB; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_RGB8; return true; case nzPixelFormat_RGBA4: format->dataFormat = GL_RGBA; format->dataType = GL_UNSIGNED_SHORT_4_4_4_4; format->internalFormat = GL_RGBA4; return true; case nzPixelFormat_RGBA8: format->dataFormat = GL_RGBA; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_RGBA8; return true; case nzPixelFormat_Depth16: format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_DEPTH_COMPONENT16; return true; case nzPixelFormat_Depth24: format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_DEPTH_COMPONENT24; return true; case nzPixelFormat_Depth24Stencil8: format->dataFormat = GL_DEPTH_STENCIL; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_DEPTH24_STENCIL8; return true; case nzPixelFormat_Depth32: format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_DEPTH_COMPONENT32; return true; case nzPixelFormat_Stencil1: if (type == FormatType_Texture) // Les formats de stencil ne sont pas supportés par les textures return false; else { format->dataFormat = GL_NONE; format->dataType = GL_NONE; format->internalFormat = GL_STENCIL_INDEX1; return true; } case nzPixelFormat_Stencil4: if (type == FormatType_Texture) return false; else { format->dataFormat = GL_NONE; format->dataType = GL_NONE; format->internalFormat = GL_STENCIL_INDEX4; return true; } case nzPixelFormat_Stencil8: if (type == FormatType_Texture) return false; else { format->dataFormat = GL_NONE; format->dataType = GL_NONE; format->internalFormat = GL_STENCIL_INDEX8; return true; } case nzPixelFormat_Stencil16: if (type == FormatType_Texture) return false; else { format->dataFormat = GL_NONE; format->dataType = GL_NONE; format->internalFormat = GL_STENCIL_INDEX16; return true; } case nzPixelFormat_Undefined: break; } NazaraError("Invalid pixel format"); return false; } void Uninitialize() { NzContext::Uninitialize(); for (bool& ext : openGLextensions) ext = false; openGLextensionSet.clear(); openGLversion = 0; UnloadLibrary(); } GLenum Attachment[nzAttachmentPoint_Max+1] = { GL_COLOR_ATTACHMENT0, // nzAttachmentPoint_Color GL_DEPTH_ATTACHMENT, // nzAttachmentPoint_Depth GL_DEPTH_STENCIL_ATTACHMENT, // nzAttachmentPoint_DepthStencil GL_STENCIL_ATTACHMENT // nzAttachmentPoint_Stencil }; nzUInt8 AttributeIndex[nzElementUsage_Max+1] = { 2, // nzElementUsage_Diffuse 1, // nzElementUsage_Normal 0, // nzElementUsage_Position 3, // nzElementUsage_Tangent 4 // nzElementUsage_TexCoord (Doit être le dernier de la liste car extensible) }; GLenum BlendFunc[nzBlendFunc_Max+1] = { GL_DST_ALPHA, // nzBlendFunc_DestAlpha GL_DST_COLOR, // nzBlendFunc_DestColor GL_SRC_ALPHA, // nzBlendFunc_SrcAlpha GL_SRC_COLOR, // nzBlendFunc_SrcColor GL_ONE_MINUS_DST_ALPHA, // nzBlendFunc_InvDestAlpha GL_ONE_MINUS_DST_COLOR, // nzBlendFunc_InvDestColor GL_ONE_MINUS_SRC_ALPHA, // nzBlendFunc_InvSrcAlpha GL_ONE_MINUS_SRC_COLOR, // nzBlendFunc_InvSrcColor GL_ONE, // nzBlendFunc_One GL_ZERO // nzBlendFunc_Zero }; GLenum BufferLock[nzBufferAccess_Max+1] = { GL_WRITE_ONLY, // nzBufferAccess_DiscardAndWrite GL_READ_ONLY, // nzBufferAccess_ReadOnly GL_READ_WRITE, // nzBufferAccess_ReadWrite GL_WRITE_ONLY // nzBufferAccess_WriteOnly }; GLenum BufferLockRange[nzBufferAccess_Max+1] = { GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_DiscardAndWrite GL_MAP_READ_BIT, // nzBufferAccess_ReadOnly GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_ReadWrite GL_MAP_WRITE_BIT // nzBufferAccess_WriteOnly }; GLenum BufferTarget[nzBufferType_Max+1] = { GL_ELEMENT_ARRAY_BUFFER, // nzBufferType_Index, GL_ARRAY_BUFFER, // nzBufferType_Vertex }; GLenum BufferTargetBinding[nzBufferType_Max+1] = { GL_ELEMENT_ARRAY_BUFFER_BINDING, // nzBufferType_Index, GL_ARRAY_BUFFER_BINDING, // nzBufferType_Vertex }; GLenum BufferUsage[nzBufferUsage_Max+1] = { // J'ai choisi DYNAMIC à la place de STREAM car DYNAMIC semble plus adapté au profil "une mise à jour pour quelques rendus" // Ce qui est je pense le scénario qui arrivera le plus souvent (Prévoir une option pour permettre d'utiliser le STREAM_DRAW ?) // Source: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=160839 GL_DYNAMIC_DRAW, // nzBufferUsage_Dynamic GL_STATIC_DRAW // nzBufferUsage_Static }; GLenum CubemapFace[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, // nzCubemapFace_PositiveX GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // nzCubemapFace_NegativeX GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_PositiveY GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_NegativeY GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // nzCubemapFace_PositiveZ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // nzCubemapFace_NegativeZ }; GLenum ElementType[nzElementType_Max+1] = { GL_UNSIGNED_BYTE, // nzElementType_Color GL_DOUBLE, // nzElementType_Double1 GL_DOUBLE, // nzElementType_Double2 GL_DOUBLE, // nzElementType_Double3 GL_DOUBLE, // nzElementType_Double4 GL_FLOAT, // nzElementType_Float1 GL_FLOAT, // nzElementType_Float2 GL_FLOAT, // nzElementType_Float3 GL_FLOAT // nzElementType_Float4 }; GLenum FaceCulling[nzFaceCulling_Max+1] = { GL_BACK, // nzFaceCulling_Back GL_FRONT, // nzFaceCulling_Front GL_FRONT_AND_BACK // nzFaceCulling_FrontAndBack }; GLenum FaceFilling[nzFaceFilling_Max+1] = { GL_POINT, // nzFaceFilling_Point GL_LINE, // nzFaceFilling_Line GL_FILL // nzFaceFilling_Fill }; GLenum PrimitiveType[nzPrimitiveType_Max+1] = { GL_LINES, // nzPrimitiveType_LineList, GL_LINE_STRIP, // nzPrimitiveType_LineStrip, GL_POINTS, // nzPrimitiveType_PointList, GL_TRIANGLES, // nzPrimitiveType_TriangleList, GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip, GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan }; GLenum RendererComparison[nzRendererComparison_Max+1] = { GL_ALWAYS, // nzRendererComparison_Always GL_EQUAL, // nzRendererComparison_Equal GL_GREATER, // nzRendererComparison_Greater GL_GEQUAL, // nzRendererComparison_GreaterOrEqual GL_LESS, // nzRendererComparison_Less GL_LEQUAL, // nzRendererComparison_LessOrEqual GL_NEVER // nzRendererComparison_Never }; GLenum RendererParameter[nzRendererParameter_Max+1] = { GL_BLEND, // nzRendererParameter_Blend GL_NONE, // nzRendererParameter_ColorWrite GL_DEPTH_TEST, // nzRendererParameter_DepthTest GL_NONE, // nzRendererParameter_DepthWrite GL_CULL_FACE, // nzRendererParameter_FaceCulling GL_STENCIL_TEST // nzRendererParameter_Stencil }; GLenum ShaderType[nzShaderType_Max+1] = { GL_FRAGMENT_SHADER, // nzShaderType_Fragment GL_GEOMETRY_SHADER, // nzShaderType_Geometry GL_VERTEX_SHADER // nzShaderType_Vertex }; GLenum StencilOperation[nzStencilOperation_Max+1] = { GL_DECR, // nzStencilOperation_Decrement GL_DECR_WRAP, // nzStencilOperation_DecrementToSaturation GL_INCR, // nzStencilOperation_Increment GL_INCR_WRAP, // nzStencilOperation_IncrementToSaturation GL_INVERT, // nzStencilOperation_Invert GL_KEEP, // nzStencilOperation_Keep GL_REPLACE, // nzStencilOperation_Replace GL_ZERO // nzStencilOperation_Zero }; GLenum TextureTarget[nzImageType_Max+1] { GL_TEXTURE_1D, // nzImageType_1D GL_TEXTURE_1D_ARRAY, // nzImageType_1D_Array GL_TEXTURE_2D, // nzImageType_2D GL_TEXTURE_2D_ARRAY, // nzImageType_2D_Array GL_TEXTURE_3D, // nzImageType_3D GL_TEXTURE_CUBE_MAP // nzImageType_Cubemap }; GLenum TextureTargetBinding[nzImageType_Max+1] { GL_TEXTURE_BINDING_1D, // nzImageType_1D GL_TEXTURE_BINDING_1D_ARRAY, // nzImageType_1D_Array GL_TEXTURE_BINDING_2D, // nzImageType_2D GL_TEXTURE_BINDING_2D_ARRAY, // nzImageType_2D_Array GL_TEXTURE_BINDING_3D, // nzImageType_3D GL_TEXTURE_BINDING_CUBE_MAP // nzImageType_Cubemap }; GLenum TextureTargetProxy[nzImageType_Max+1] { GL_PROXY_TEXTURE_1D, // nzImageType_1D GL_PROXY_TEXTURE_1D_ARRAY, // nzImageType_1D_Array GL_PROXY_TEXTURE_2D, // nzImageType_2D GL_PROXY_TEXTURE_2D_ARRAY, // nzImageType_2D_Array GL_PROXY_TEXTURE_3D, // nzImageType_3D GL_PROXY_TEXTURE_CUBE_MAP // nzImageType_Cubemap }; } PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr; PFNGLATTACHSHADERPROC glAttachShader = nullptr; PFNGLBEGINQUERYPROC glBeginQuery = nullptr; PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = nullptr; PFNGLBINDBUFFERPROC glBindBuffer = nullptr; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr; PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation = 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; PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture = nullptr; PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = nullptr; PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = nullptr; PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = nullptr; PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = 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; PFNGLGETFLOATVPROC glGetFloatv = 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; PFNGLPOINTSIZEPROC glPointSize = 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