diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp index 8e7b251de..d2cc4248f 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp @@ -52,7 +52,10 @@ namespace Nz::GL enum class Extension { + ClipControl, + DebugOutput, DepthClamp, + PolygonMode, SpirV, StorageBuffers, TextureCompressionS3tc, @@ -149,6 +152,8 @@ namespace Nz::GL inline bool IsExtensionSupported(Extension extension) const; inline bool IsExtensionSupported(const std::string& extension) const; + inline bool HasZeroToOneDepth() const; + bool Initialize(const ContextParams& params); inline void NotifyBufferDestruction(GLuint buffer) const; @@ -253,6 +258,7 @@ namespace Nz::GL mutable State m_state; mutable bool m_didCollectErrors; mutable bool m_hadAnyError; + bool m_hasZeroToOneDepth; }; } diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Context.inl b/include/Nazara/OpenGLRenderer/Wrapper/Context.inl index 27cf83ab6..d9e3c1418 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Context.inl +++ b/include/Nazara/OpenGLRenderer/Wrapper/Context.inl @@ -51,6 +51,11 @@ namespace Nz::GL return m_supportedExtensions.find(extension) != m_supportedExtensions.end(); } + inline bool Context::HasZeroToOneDepth() const + { + return m_hasZeroToOneDepth; + } + inline void Context::NotifyBufferDestruction(GLuint buffer) const { for (GLuint& boundBuffer : m_state.bufferTargets) diff --git a/include/Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp b/include/Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp index 2a5099839..54ce04290 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp @@ -13,7 +13,7 @@ #include #include -// Define some OpenGL (not ES) extensions +// Define some OpenGL (not ES) defines/function types #define GL_POINT 0x1B00 #define GL_LINE 0x1B01 #define GL_FILL 0x1B02 @@ -22,8 +22,21 @@ #define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F typedef void (GL_APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf); typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); + +// Clip control (OpenGL 4.5) +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_ZERO_TO_ONE 0x935F +#define GL_CLIP_ORIGIN 0x935C +#define GL_CLIP_DEPTH_MODE 0x935D +typedef void (GL_APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); + +// SPIR-V shaders (OpenGL 4.6) typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue); +/*** Functions ***/ + // OpenGL core #define NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(cb, extCb) \ cb(glActiveTexture, PFNGLACTIVETEXTUREPROC) \ @@ -183,6 +196,8 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLch extCb(glObjectLabel, PFNGLOBJECTLABELPROC) \ extCb(glPopDebugGroup, PFNGLPOPDEBUGGROUPPROC) \ extCb(glPushDebugGroup, PFNGLPUSHDEBUGGROUPPROC) \ + /* OpenGL 4.5 - GL_ARB_clip_control/GL_EXT_clip_control */ \ + extCb(glClipControl, PFNGLCLIPCONTROLPROC) \ /* OpenGL 4.6 - GL_ARB_spirv_extensions */\ extCb(glSpecializeShader, PFNGLSPECIALIZESHADERPROC) \ diff --git a/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp b/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp index cedc2f35e..f32163efb 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp @@ -96,8 +96,11 @@ namespace Nz { return context.IsExtensionSupported(std::string(ext)); }; + env.flipYPosition = true; - env.remapZPosition = true; + + if (!context.HasZeroToOneDepth()) + env.remapZPosition = true; nzsl::GlslWriter writer; writer.SetEnv(env); diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp index 64161b09a..73cf110bd 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp @@ -109,7 +109,8 @@ namespace Nz::GL m_vaoCache(*this), m_device(device), m_didCollectErrors(false), - m_hadAnyError(false) + m_hadAnyError(false), + m_hasZeroToOneDepth(false) { } @@ -381,6 +382,22 @@ namespace Nz::GL m_extensionStatus.fill(ExtensionStatus::NotSupported); + // Clip control + if (m_params.type == ContextType::OpenGL && glVersion >= 450) + m_extensionStatus[UnderlyingCast(Extension::ClipControl)] = ExtensionStatus::Core; + else if (m_supportedExtensions.count("GL_ARB_clip_control")) + m_extensionStatus[UnderlyingCast(Extension::ClipControl)] = ExtensionStatus::ARB; + else if (m_supportedExtensions.count("GL_EXT_clip_control")) + m_extensionStatus[UnderlyingCast(Extension::ClipControl)] = ExtensionStatus::EXT; + + // Debug output + if ((m_params.type == ContextType::OpenGL && glVersion >= 430) || (m_params.type == ContextType::OpenGL_ES && glVersion >= 320)) + m_extensionStatus[UnderlyingCast(Extension::DebugOutput)] = ExtensionStatus::Core; + else if (m_supportedExtensions.count("GL_KHR_debug")) + m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::KHR; + else if (m_supportedExtensions.count("GL_ARB_debug_output")) + m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::ARB; + // Depth clamp if (m_params.type == ContextType::OpenGL && glVersion >= 320) m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Core; @@ -391,6 +408,12 @@ namespace Nz::GL else if (m_supportedExtensions.count("GL_NV_depth_clamp")) m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Vendor; + // Polygon mode + if (m_params.type == ContextType::OpenGL) + m_extensionStatus[UnderlyingCast(Extension::PolygonMode)] = ExtensionStatus::Core; + else if (m_supportedExtensions.count("GL_NV_polygon_mode")) + m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Vendor; + // SPIR-V support if (m_params.type == ContextType::OpenGL && glVersion >= 460) m_extensionStatus[UnderlyingCast(Extension::SpirV)] = ExtensionStatus::Core; @@ -421,6 +444,14 @@ namespace Nz::GL #undef NAZARA_OPENGLRENDERER_EXT_FUNC #undef NAZARA_OPENGLRENDERER_FUNC + // Match Vulkan convention if supported (so we don't have to inject code in the shader to fix it) + if (glClipControl) + { + // TODO: Using GL_UPPER_LEFT causes some issues I still have to figure out + glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); + m_hasZeroToOneDepth = true; + } + // Always enable cubemap sampling (as it's the guaranteed behavior on Vulkan and OpenGL ES 3.0) if (m_params.type == ContextType::OpenGL && (glVersion >= 320 || m_supportedExtensions.count("GL_ARB_seamless_cube_map"))) glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); @@ -847,7 +878,14 @@ namespace Nz::GL { SymbolLoader loader(*this); - if (function == "glDebugMessageCallback") + if (function == "glClipControl") + { + constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glClipControl); + + return loader.Load(glClipControl, "glClipControlEXT", false); //< from GL_EXT_clip_control + + } + else if (function == "glDebugMessageCallback") { constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glDebugMessageCallback);