diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 721b0f5152..4ccd382f65 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -279,6 +279,7 @@ typedef float GLclampf; typedef double GLdouble; typedef unsigned int GLenum; typedef unsigned int GLbitfield; +typedef unsigned char GLboolean; GLAPI void glBegin(GLenum mode); GLAPI void glClear(GLbitfield mask); @@ -290,6 +291,7 @@ GLAPI void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a); GLAPI void glColor4fv(const GLfloat* v); GLAPI void glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a); GLAPI void glColor4ubv(const GLubyte* v); +GLAPI void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); GLAPI void glDeleteTextures(GLsizei n, const GLuint* textures); GLAPI void glEnd(); GLAPI void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal); diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index cab0b8beb4..4c1c3ade5a 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -71,6 +71,7 @@ public: virtual void gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) = 0; virtual void gl_draw_arrays(GLenum mode, GLint first, GLsizei count) = 0; virtual void gl_draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) = 0; + virtual void gl_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) = 0; virtual void present() = 0; }; diff --git a/Userland/Libraries/LibGL/GLUtils.cpp b/Userland/Libraries/LibGL/GLUtils.cpp index 77abfd8d11..67536bee26 100644 --- a/Userland/Libraries/LibGL/GLUtils.cpp +++ b/Userland/Libraries/LibGL/GLUtils.cpp @@ -45,6 +45,11 @@ void glClearDepth(GLdouble depth) g_gl_context->gl_clear_depth(depth); } +void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + g_gl_context->gl_color_mask(red, green, blue, alpha); +} + GLubyte* glGetString(GLenum name) { return g_gl_context->gl_get_string(name); diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index f23c3b941d..01cb90f209 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -1694,6 +1694,35 @@ void SoftwareGLContext::read_from_vertex_attribute_pointer(VertexAttribPointer c } } +void SoftwareGLContext::gl_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + auto options = m_rasterizer.options(); + auto mask = options.color_mask; + + if (!red) + mask &= ~0x000000ff; + else + mask |= 0x000000ff; + + if (!green) + mask &= ~0x0000ff00; + else + mask |= 0x0000ff00; + + if (!blue) + mask &= ~0x00ff0000; + else + mask |= 0x00ff0000; + + if (!alpha) + mask &= ~0xff000000; + else + mask |= 0xff000000; + + options.color_mask = mask; + 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 df7a062ab0..05a49456f7 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -81,7 +81,7 @@ public: virtual void gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) override; virtual void gl_draw_arrays(GLenum mode, GLint first, GLsizei count) override; virtual void gl_draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) override; - + virtual void gl_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) override; virtual void present() override; private: diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp index 61c17aa173..c4d29f1135 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp @@ -383,7 +383,7 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re + float_dst * dst_factor_dst_color + FloatVector4(float_dst.w(), float_dst.w(), float_dst.w(), float_dst.w()) * dst_factor_dst_alpha; - *dst = to_rgba32(*src * src_factor + float_dst * dst_factor); + *dst = (*dst & ~options.color_mask) | (to_rgba32(*src * src_factor + float_dst * dst_factor) & options.color_mask); } } } else { @@ -395,7 +395,7 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re if (~pixel_mask[y] & (1 << x)) continue; - *dst = to_rgba32(*src); + *dst = (*dst & ~options.color_mask) | (to_rgba32(*src) & options.color_mask); } } } diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.h b/Userland/Libraries/LibGL/SoftwareRasterizer.h index 6d4d15f2cf..d830dcac70 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.h +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.h @@ -28,6 +28,7 @@ struct RasterizerOptions { bool enable_blending { false }; GLenum blend_source_factor { GL_ONE }; GLenum blend_destination_factor { GL_ONE }; + u32 color_mask { 0xffffffff }; }; class SoftwareRasterizer final {