From 1bd754882ddea4d6785879118dc032098e83e679 Mon Sep 17 00:00:00 2001 From: Stephan Unverwerth Date: Sun, 16 May 2021 16:43:09 +0200 Subject: [PATCH] LibGL: Implement glAlphaFunc() This implements glAlphaFunc() for setting alpha test func and ref value and also allows enabling and disabling GL_ALPHA_TEST --- Userland/Libraries/LibGL/GL/gl.h | 20 ++++++++++- Userland/Libraries/LibGL/GLBlend.cpp | 5 +++ Userland/Libraries/LibGL/GLContext.h | 1 + .../Libraries/LibGL/SoftwareGLContext.cpp | 33 +++++++++++++++++++ Userland/Libraries/LibGL/SoftwareGLContext.h | 8 ++++- Userland/Libraries/LibGL/SoftwareRasterizer.h | 3 ++ 6 files changed, 68 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 325e0899c8..0c10917ff8 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -29,6 +29,16 @@ extern "C" { #define GL_TRIANGLE_STRIP 0x0103 #define GL_POLYGON 0x0104 +// Depth buffer and alpha test compare functions +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + // Buffer bits #define GL_COLOR_BUFFER_BIT 0x0200 #define GL_DEPTH_BUFFER_BIT 0x0400 @@ -36,6 +46,13 @@ extern "C" { // Enable capabilities #define GL_CULL_FACE 0x0B44 #define GL_DEPTH_TEST 0x0B71 + +// Alpha testing +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TEST_FUNC 0x0BC1 + +// Alpha blending #define GL_BLEND 0x0BE2 // Utility @@ -43,7 +60,7 @@ extern "C" { #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 -/* Blend factors */ +// Blend factors #define GL_ZERO 0 #define GL_ONE 1 #define GL_SRC_COLOR 0x0300 @@ -152,6 +169,7 @@ GLAPI void glFlush(); GLAPI void glFinish(); GLAPI void glBlendFunc(GLenum sfactor, GLenum dfactor); GLAPI void glShadeModel(GLenum mode); +GLAPI void glAlphaFunc(GLenum func, GLclampf ref); #ifdef __cplusplus } diff --git a/Userland/Libraries/LibGL/GLBlend.cpp b/Userland/Libraries/LibGL/GLBlend.cpp index 91bc27952a..10bec6f806 100644 --- a/Userland/Libraries/LibGL/GLBlend.cpp +++ b/Userland/Libraries/LibGL/GLBlend.cpp @@ -13,3 +13,8 @@ void glBlendFunc(GLenum sfactor, GLenum dfactor) { return g_gl_context->gl_blend_func(sfactor, dfactor); } + +void glAlphaFunc(GLenum func, GLclampf ref) +{ + return g_gl_context->gl_alpha_func(func, ref); +} diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 084c4db5da..68cfe60f29 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -51,6 +51,7 @@ public: virtual void gl_finish() = 0; virtual void gl_blend_func(GLenum src_factor, GLenum dst_factor) = 0; virtual void gl_shade_model(GLenum mode) = 0; + virtual void gl_alpha_func(GLenum func, GLclampf ref) = 0; virtual void present() = 0; }; diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 8e8f6e2bd2..365d5df6dd 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -688,6 +688,11 @@ void SoftwareGLContext::gl_enable(GLenum capability) rasterizer_options.enable_blending = true; update_rasterizer_options = true; break; + case GL_ALPHA_TEST: + m_alpha_test_enabled = true; + rasterizer_options.enable_alpha_test = true; + update_rasterizer_options = true; + break; default: m_error = GL_INVALID_ENUM; break; @@ -723,6 +728,11 @@ void SoftwareGLContext::gl_disable(GLenum capability) rasterizer_options.enable_blending = false; update_rasterizer_options = false; break; + case GL_ALPHA_TEST: + m_alpha_test_enabled = false; + rasterizer_options.enable_alpha_test = false; + update_rasterizer_options = false; + break; default: m_error = GL_INVALID_ENUM; break; @@ -946,6 +956,29 @@ void SoftwareGLContext::gl_shade_model(GLenum mode) m_rasterizer.set_options(options); } +void SoftwareGLContext::gl_alpha_func(GLenum func, GLclampf ref) +{ + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_alpha_func, func, ref); + + if (m_in_draw_state) { + m_error = GL_INVALID_OPERATION; + return; + } + + if (func < GL_NEVER || func > GL_ALWAYS) { + m_error = GL_INVALID_ENUM; + return; + } + + m_alpha_test_func = func; + m_alpha_test_ref_value = ref; + + auto options = m_rasterizer.options(); + options.alpha_test_func = m_alpha_test_func; + options.alpha_test_ref_value = m_alpha_test_ref_value; + m_rasterizer.set_options(options); +} + void SoftwareGLContext::present() { m_rasterizer.blit_to(*m_frontbuffer); diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 9a1183fd80..dcfe95fcd3 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -57,6 +57,7 @@ public: virtual void gl_finish() override; virtual void gl_blend_func(GLenum src_factor, GLenum dst_factor) override; virtual void gl_shade_model(GLenum mode) override; + virtual void gl_alpha_func(GLenum func, GLclampf ref) override; virtual void present() override; @@ -111,6 +112,10 @@ private: GLenum m_blend_source_factor = GL_ONE; GLenum m_blend_destination_factor = GL_ZERO; + bool m_alpha_test_enabled = false; + GLenum m_alpha_test_func = GL_ALWAYS; + GLclampf m_alpha_test_ref_value = 0; + NonnullRefPtr m_frontbuffer; Clipper m_clipper; @@ -164,7 +169,8 @@ private: decltype(&SoftwareGLContext::gl_cull_face), decltype(&SoftwareGLContext::gl_call_list), decltype(&SoftwareGLContext::gl_blend_func), - decltype(&SoftwareGLContext::gl_shade_model)>; + decltype(&SoftwareGLContext::gl_shade_model), + decltype(&SoftwareGLContext::gl_alpha_func)>; using ExtraSavedArguments = Variant< FloatMatrix4x4>; diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.h b/Userland/Libraries/LibGL/SoftwareRasterizer.h index 10fb57d963..62c7e66a73 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.h +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.h @@ -18,6 +18,9 @@ namespace GL { struct RasterizerOptions { bool shade_smooth { true }; bool enable_depth_test { false }; + bool enable_alpha_test { false }; + GLenum alpha_test_func { GL_ALWAYS }; + float alpha_test_ref_value { 0 }; bool enable_blending { false }; GLenum blend_source_factor { GL_ONE }; GLenum blend_destination_factor { GL_ONE };