diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 712cff830a..606d76ab45 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -370,6 +370,7 @@ GLAPI void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void GLAPI void glDrawArrays(GLenum mode, GLint first, GLsizei count); GLAPI void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices); GLAPI void glDepthRange(GLdouble nearVal, GLdouble farVal); +GLAPI void glDepthFunc(GLenum func); #ifdef __cplusplus } diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 32e2dae96b..f788361970 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -75,6 +75,7 @@ public: virtual void gl_get_booleanv(GLenum pname, GLboolean* data) = 0; virtual void gl_get_integerv(GLenum pname, GLint* data) = 0; virtual void gl_depth_range(GLdouble min, GLdouble max) = 0; + virtual void gl_depth_func(GLenum func) = 0; virtual void present() = 0; }; diff --git a/Userland/Libraries/LibGL/GLUtils.cpp b/Userland/Libraries/LibGL/GLUtils.cpp index e771d3f860..af7a07e79b 100644 --- a/Userland/Libraries/LibGL/GLUtils.cpp +++ b/Userland/Libraries/LibGL/GLUtils.cpp @@ -124,3 +124,8 @@ void glDepthRange(GLdouble min, GLdouble max) { g_gl_context->gl_depth_range(min, max); } + +void glDepthFunc(GLenum func) +{ + g_gl_context->gl_depth_func(func); +} diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index f35fbe54a8..981fb0e03c 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -1653,6 +1653,27 @@ void SoftwareGLContext::gl_depth_range(GLdouble min, GLdouble max) m_rasterizer.set_options(options); } +void SoftwareGLContext::gl_depth_func(GLenum func) +{ + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_depth_func, func); + + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + + RETURN_WITH_ERROR_IF(!(func == GL_NEVER + || func == GL_LESS + || func == GL_EQUAL + || func == GL_LEQUAL + || func == GL_GREATER + || func == GL_NOTEQUAL + || func == GL_GEQUAL + || func == GL_ALWAYS), + GL_INVALID_ENUM); + + auto options = m_rasterizer.options(); + options.depth_func = func; + m_rasterizer.set_options(options); +} + // General helper function to read arbitrary vertex attribute data into a float array void SoftwareGLContext::read_from_vertex_attribute_pointer(VertexAttribPointer const& attrib, int index, float* elements, bool normalize) { diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 9d70d09a97..f5055cb530 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -85,6 +85,7 @@ public: virtual void gl_get_booleanv(GLenum pname, GLboolean* data) override; virtual void gl_get_integerv(GLenum pname, GLint* data) override; virtual void gl_depth_range(GLdouble min, GLdouble max) override; + virtual void gl_depth_func(GLenum func) override; virtual void present() override; private: diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp index 13a4e357d1..b134f4a30e 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp @@ -261,8 +261,36 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re auto barycentric = FloatVector3(coords.x(), coords.y(), coords.z()) * one_over_area; float z = interpolate(triangle.vertices[0].z, triangle.vertices[1].z, triangle.vertices[2].z, barycentric); z = options.depth_min + (options.depth_max - options.depth_min) * (z + 1) / 2; - - if (z >= *depth) { + + bool pass = false; + switch (options.depth_func) { + case GL_ALWAYS: + pass = true; + break; + case GL_NEVER: + pass = false; + break; + case GL_GREATER: + pass = z > *depth; + break; + case GL_GEQUAL: + pass = z >= *depth; + break; + case GL_NOTEQUAL: + pass = z != *depth; + break; + case GL_EQUAL: + pass = z == *depth; + break; + case GL_LEQUAL: + pass = z <= *depth; + break; + case GL_LESS: + pass = z < *depth; + break; + } + + if (!pass) { pixel_mask[y] ^= 1 << x; continue; } diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.h b/Userland/Libraries/LibGL/SoftwareRasterizer.h index cb5255c7e8..63c2c752cf 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.h +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.h @@ -31,6 +31,7 @@ struct RasterizerOptions { u32 color_mask { 0xffffffff }; float depth_min { 0 }; float depth_max { 1 }; + GLenum depth_func { GL_LESS }; }; class SoftwareRasterizer final {