diff --git a/Tests/LibGL/TestAPI.cpp b/Tests/LibGL/TestAPI.cpp index d5ec47631cd..b77c9c214c5 100644 --- a/Tests/LibGL/TestAPI.cpp +++ b/Tests/LibGL/TestAPI.cpp @@ -61,3 +61,51 @@ TEST_CASE(0003_gl_bind_buffer_names_must_be_allocated) glBindBuffer(GL_ARRAY_BUFFER, 123); EXPECT_EQ(glGetError(), static_cast(GL_INVALID_VALUE)); } + +TEST_CASE(0004_gl_color_clear_value) +{ + auto context = create_testing_context(); + + Array clear_color; + glGetDoublev(GL_COLOR_CLEAR_VALUE, clear_color.data()); + EXPECT_EQ(clear_color[0], 0.); + EXPECT_EQ(clear_color[1], 0.); + EXPECT_EQ(clear_color[2], 0.); + EXPECT_EQ(clear_color[3], 0.); + + glClearColor(.1f, .2f, .3f, .4f); + + glGetDoublev(GL_COLOR_CLEAR_VALUE, clear_color.data()); + EXPECT_APPROXIMATE(clear_color[0], .1); + EXPECT_APPROXIMATE(clear_color[1], .2); + EXPECT_APPROXIMATE(clear_color[2], .3); + EXPECT_APPROXIMATE(clear_color[3], .4); +} + +TEST_CASE(0005_gl_depth_clear_value) +{ + auto context = create_testing_context(); + + GLdouble clear_depth; + glGetDoublev(GL_DEPTH_CLEAR_VALUE, &clear_depth); + EXPECT_EQ(clear_depth, 1.); + + glClearDepth(.1f); + + glGetDoublev(GL_DEPTH_CLEAR_VALUE, &clear_depth); + EXPECT_APPROXIMATE(clear_depth, .1); +} + +TEST_CASE(0006_gl_stencil_clear_value) +{ + auto context = create_testing_context(); + + GLint clear_stencil; + glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clear_stencil); + EXPECT_EQ(clear_stencil, 0); + + glClearStencil(255); + + glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clear_stencil); + EXPECT_EQ(clear_stencil, 255); +} diff --git a/Userland/Libraries/LibGL/ContextParameter.cpp b/Userland/Libraries/LibGL/ContextParameter.cpp index 15354eb9c3a..7e901b7202c 100644 --- a/Userland/Libraries/LibGL/ContextParameter.cpp +++ b/Userland/Libraries/LibGL/ContextParameter.cpp @@ -30,6 +30,18 @@ Optional GLContext::get_context_parameter(GLenum name) return ContextParameter { .type = GL_INT, .value = { .integer_value = sizeof(u8) * 8 } }; case GL_CLIENT_ACTIVE_TEXTURE: return ContextParameter { .type = GL_INT, .value = { .integer_value = static_cast(GL_TEXTURE0 + m_client_active_texture) } }; + case GL_COLOR_CLEAR_VALUE: + return ContextParameter { + .type = GL_DOUBLE, + .count = 4, + .value = { + .double_list = { + static_cast(m_clear_color.x()), + static_cast(m_clear_color.y()), + static_cast(m_clear_color.z()), + static_cast(m_clear_color.w()), + } } + }; case GL_COLOR_MATERIAL: return ContextParameter { .type = GL_BOOL, .is_capability = true, .value = { .boolean_value = m_color_material_enabled } }; case GL_COLOR_MATERIAL_FACE: @@ -52,6 +64,8 @@ Optional GLContext::get_context_parameter(GLenum name) return ContextParameter { .type = GL_BOOL, .is_capability = true, .value = { .boolean_value = m_cull_faces } }; case GL_DEPTH_BITS: return ContextParameter { .type = GL_INT, .value = { .integer_value = sizeof(float) * 8 } }; + case GL_DEPTH_CLEAR_VALUE: + return ContextParameter { .type = GL_DOUBLE, .value = { .double_value = static_cast(m_clear_depth) } }; case GL_DEPTH_TEST: return ContextParameter { .type = GL_BOOL, .is_capability = true, .value = { .boolean_value = m_depth_test_enabled } }; case GL_DITHER: diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 56f617ef1a8..008f88e620e 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -103,10 +103,12 @@ extern "C" { #define GL_COLOR_MATERIAL 0x0B57 #define GL_FOG_START 0x0B63 #define GL_FOG_END 0x0B64 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 #define GL_STENCIL_CLEAR_VALUE 0x0B91 #define GL_MATRIX_MODE 0x0BA0 #define GL_NORMALIZE 0x0BA1 #define GL_VIEWPORT 0x0BA2 +#define GL_COLOR_CLEAR_VALUE 0x0C22 #define GL_DOUBLEBUFFER 0x0C32 #define GL_TEXTURE_GEN_S 0x0C60 #define GL_TEXTURE_GEN_T 0x0C61 diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 3b1b1b27d1d..1808a6bc4f9 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -107,12 +107,6 @@ public: NonnullRefPtr frontbuffer() const { return m_frontbuffer; }; void present(); - // Used by WebGL to preserve the clear values when implicitly clearing the front buffer. - // FIXME: Add ContextParameters for these and expose them through methods such as gl_get_floatv instead of having a public API like this. - FloatVector4 current_clear_color() const { return m_clear_color; } - GLdouble current_clear_depth() const { return m_clear_depth; } - GLint current_clear_stencil() const { return m_clear_stencil; } - void gl_begin(GLenum mode); void gl_clear(GLbitfield mask); void gl_clear_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); diff --git a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp index 402c0790481..b501b04084d 100644 --- a/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp +++ b/Userland/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp @@ -52,9 +52,14 @@ void WebGLRenderingContextBase::present() // This default behavior can be changed by setting the preserveDrawingBuffer attribute of the WebGLContextAttributes object. // If this flag is true, the contents of the drawing buffer shall be preserved until the author either clears or overwrites them." if (!m_context_creation_parameters.preserve_drawing_buffer) { - auto current_clear_color = m_context->current_clear_color(); - auto current_clear_depth = m_context->current_clear_depth(); - auto current_clear_stencil = m_context->current_clear_stencil(); + Array current_clear_color; + m_context->gl_get_doublev(GL_COLOR_CLEAR_VALUE, current_clear_color.data()); + + GLdouble current_clear_depth; + m_context->gl_get_doublev(GL_DEPTH_CLEAR_VALUE, ¤t_clear_depth); + + GLint current_clear_stencil; + m_context->gl_get_integerv(GL_STENCIL_CLEAR_VALUE, ¤t_clear_stencil); // The implicit clear value for the color buffer is (0, 0, 0, 0) m_context->gl_clear_color(0, 0, 0, 0);