From 8da082f805d4ed19be9764f5cafe957ccec8fd28 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 2 Oct 2026 12:50:36 -0400 Subject: [PATCH] [Fix] (State): start the clear colour at GL's (0, 0, 0, 0), not opaque black --- MobileGL/MG_Pipe/MGPipeValueTypes.h | 6 ++++-- MobileGL/MG_Test/State/RenderStateTest.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Pipe/MGPipeValueTypes.h b/MobileGL/MG_Pipe/MGPipeValueTypes.h index 5749fb4d..3b04eb83 100644 --- a/MobileGL/MG_Pipe/MGPipeValueTypes.h +++ b/MobileGL/MG_Pipe/MGPipeValueTypes.h @@ -304,8 +304,10 @@ namespace MobileGL { Bool DepthClampEnabled = false; Bool TextureCubeMapSeamlessEnabled = false; - // Clear State - FloatVec4 ClearColor = FloatVec4(0.0f, 0.0f, 0.0f, 1.0f); + // Clear State. GL's initial clear colour is (0, 0, 0, 0) (GL 4.6 core table 23.24): an + // application that never calls glClearColor - or caches it and skips the redundant call - + // clears to transparent, and offscreen layers depend on it. + FloatVec4 ClearColor = FloatVec4(0.0f, 0.0f, 0.0f, 0.0f); Float ClearDepth = 1.0f; Uint32 ClearStencil = 0; FloatVec4 BlendColor = FloatVec4(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/MobileGL/MG_Test/State/RenderStateTest.cpp b/MobileGL/MG_Test/State/RenderStateTest.cpp index 986f056b..0f883a34 100644 --- a/MobileGL/MG_Test/State/RenderStateTest.cpp +++ b/MobileGL/MG_Test/State/RenderStateTest.cpp @@ -645,6 +645,21 @@ TEST_F(RenderStateTest, TheFirstScissorWriteBumpsTheVersionEvenWhenTheValueDoesN // were absent too, which is what KHR-GL4x.tessellation_shader.single. // default_values_of_context_wide_properties dies on. +// GL 4.6 core table 23.24 / ES 3.2 table 21.13: GL_COLOR_CLEAR_VALUE starts at (0, 0, 0, 0). An +// opaque-black default made every glClear of an application that relies on the initial value - +// a layer that caches GL state and skips the redundant glClearColor(0, 0, 0, 0) - write alpha 1, +// so offscreen layers meant to be transparent composited as solid black squares. +TEST_F(RenderStateTest, ClearColorStartsAtTransparentBlack) { + const SharedPtr previous = MG_State::pGLContext; + MG_State::pGLContext = MakeShared(); + GLfloat clear[4] = {-1.0f, -1.0f, -1.0f, -1.0f}; + MG_Impl::GLImpl::GetFloatv(GL_COLOR_CLEAR_VALUE, clear); + const GLenum error = MG_Impl::GLImpl::GetError(); + MG_State::pGLContext = previous; + EXPECT_EQ(error, GL_NO_ERROR); + for (const GLfloat channel : clear) EXPECT_FLOAT_EQ(channel, 0.0f); +} + TEST_F(RenderStateTest, PatchDefaultLevelsStartAtTheGLDefault) { GLfloat outer[4] = {-1.0f, -1.0f, -1.0f, -1.0f}; MG_Impl::GLImpl::GetFloatv(GL_PATCH_DEFAULT_OUTER_LEVEL, outer);