From 63295b549339e2d08e5efec22a67ea70a25d67f6 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 26 Oct 2025 22:43:42 +0800 Subject: [PATCH 1/7] [Chore]: fix compilation on Windows --- MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index 97f7aa99..e1c7c20d 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -443,6 +443,7 @@ namespace MobileGL { static const char* EGLLibs[] = {"libEGL", nullptr}; void* OpenLib(const char** names, const char* override) { +#ifndef __WIN32 void* lib = nullptr; char path_name[PATH_MAX + 1]; @@ -464,6 +465,9 @@ namespace MobileGL { } } return lib; +#else + return nullptr; +#endif } void LoadLibs() { @@ -473,7 +477,11 @@ namespace MobileGL { } void* ProcAddress(void* lib, const char* name) { +#ifndef __WIN32 return dlsym(lib, name); +#else + return nullptr; +#endif } void InitGLESCapabilities() { From f951f0451fee000795ca4293416cf980bd50a8a8 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 26 Oct 2025 23:00:48 +0800 Subject: [PATCH 2/7] [Chore] (MG_Test/ProgramTest): add more checks to ProgramTest --- MobileGL/MG_Test/Program/ProgramTest.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MobileGL/MG_Test/Program/ProgramTest.cpp b/MobileGL/MG_Test/Program/ProgramTest.cpp index 214e99cb..41af7564 100644 --- a/MobileGL/MG_Test/Program/ProgramTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramTest.cpp @@ -207,6 +207,10 @@ TEST_F(ProgramTest, UniformMatrixFunctions) { UseProgram(program); + int uniformCount = 0; + GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount); + ASSERT_LT(uniformCount, 4000); + // Test UniformMatrix2fv auto locProjMat = GetUniformLocation(program, "ProjMat"); ASSERT_NE(locProjMat, -1); @@ -268,6 +272,10 @@ TEST_F(ProgramTest, UniformMatrixTranspose) { UseProgram(program); + int uniformCount = 0; + GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount); + ASSERT_LT(uniformCount, 4000); + // Test 2x2 matrix transpose auto locMat2 = GetUniformLocation(program, "TestMat2"); ASSERT_NE(locMat2, -1); @@ -428,6 +436,10 @@ TEST_F(ProgramTest, UniformLocationGaps) { UseProgram(program); + int uniformCount = 0; + GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount); + ASSERT_LT(uniformCount, 4000); + // Test that uniform locations are correctly assigned even with gaps // ProjMat is at location 0 ASSERT_EQ(GetUniformLocation(program, "ProjMat"), 0); From b91f180c7b0b2bbf7d9014f63d944eb05189bfeb Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sun, 26 Oct 2025 23:06:28 +0800 Subject: [PATCH 3/7] [Fix]: fix compilation on Windows again --- MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index e1c7c20d..0cc5cc15 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -443,7 +443,7 @@ namespace MobileGL { static const char* EGLLibs[] = {"libEGL", nullptr}; void* OpenLib(const char** names, const char* override) { -#ifndef __WIN32 +#if !defined(__WIN32) && !defined(_WIN32) void* lib = nullptr; char path_name[PATH_MAX + 1]; @@ -477,7 +477,7 @@ namespace MobileGL { } void* ProcAddress(void* lib, const char* name) { -#ifndef __WIN32 +#if !defined(__WIN32) && !defined(_WIN32) return dlsym(lib, name); #else return nullptr; From d73bd5dcd20a484896319e05c08a9116fc90aaee Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 27 Oct 2025 10:51:41 +0800 Subject: [PATCH 4/7] [Fix] (MG_State/ProgramObject): Properly allocate location for location-not-explicitly-defined uniforms --- .../GLState/ProgramState/ProgramObject.cpp | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index afabb5a8..ade6c8cb 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -69,31 +69,63 @@ namespace MobileGL { return; } + // ------------ Uniforms (GL Plain) ---------------- + // Allocate uniform locations m_activeUniformCount = m_program->getNumUniformVariables(); for (int i = 0; i < m_activeUniformCount; i++) { auto& uniform = m_program->getUniform(i); auto location = uniform.layoutLocation(); - if (location >= 0) { + if (location != 4095) { m_maxUniformLocation = std::max(m_maxUniformLocation, location); } m_uniformNameMaxLength = std::max(m_uniformNameMaxLength, (Int)uniform.name.length()); m_uniformLocations[uniform.name] = location; } + if (m_maxUniformLocation + 1 < m_activeUniformCount) { + // This means we have fewer than enough gaps to fit + // unallocated uniforms + m_maxUniformLocation = m_activeUniformCount; + } + + // i-th elements refers to uniform at layout(location = i, ...) + // Be aware, there could be gaps in between these vectors + // Locations can be not sequential m_uniformNames.resize(m_maxUniformLocation + 1); - m_uniformTypes.resize(m_maxUniformLocation + 1); + m_uniformTypes.resize(m_maxUniformLocation + 1, GL_ZERO); m_uniformIsOpaqueType.resize(m_maxUniformLocation + 1); m_uniformOffsets.resize(m_maxUniformLocation + 1); m_uniformArraySizes.resize(m_maxUniformLocation + 1); + Vector unallocatedUniformIndex; + + // Populate vector with already allocated location for (int i = 0; i < m_activeUniformCount; i++) { auto& uniform = m_program->getUniform(i); auto location = uniform.layoutLocation(); - if (location >= 0 && location < (int)m_uniformNames.size()) { - m_uniformNames[location] = uniform.name; - m_uniformTypes[location] = uniform.glDefineType; - m_uniformIsOpaqueType[location] = uniform.getType()->isOpaque(); - m_uniformArraySizes[location] = uniform.size; + if (location >= m_uniformNames.size()) { + unallocatedUniformIndex.emplace_back(i); + continue; // will allocate unallocated uniforms later + } + m_uniformNames[location] = uniform.name; + m_uniformTypes[location] = uniform.glDefineType; + m_uniformIsOpaqueType[location] = uniform.getType()->isOpaque(); + m_uniformArraySizes[location] = uniform.size; + } + + SizeT locNeedle = 0; + for (auto index: unallocatedUniformIndex) { + auto& uniform = m_program->getUniform(index); + for (; locNeedle <= m_maxUniformLocation; locNeedle++) { + if (m_uniformTypes[locNeedle] != GL_ZERO) + continue; + // Found a vacant location at locNeedle + m_uniformNames[locNeedle] = uniform.name; + m_uniformTypes[locNeedle] = uniform.glDefineType; + m_uniformIsOpaqueType[locNeedle] = uniform.getType()->isOpaque(); + m_uniformArraySizes[locNeedle] = uniform.size; + m_uniformLocations[uniform.name] = locNeedle; + break; } } From 5e5d0f3dbef35d28b5b014b3ac296f1914695995 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 27 Oct 2025 10:53:06 +0800 Subject: [PATCH 5/7] [Feat] (MG_Test/Program): add test for real shader (Minecraft `position_tex`) --- MobileGL/MG_Test/Program/ProgramTest.cpp | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/MobileGL/MG_Test/Program/ProgramTest.cpp b/MobileGL/MG_Test/Program/ProgramTest.cpp index 41af7564..f5e20e65 100644 --- a/MobileGL/MG_Test/Program/ProgramTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramTest.cpp @@ -492,3 +492,75 @@ TEST_F(ProgramTest, UniformLocationGaps) { ASSERT_EQ(redVal[1], 3.0); ASSERT_EQ(redVal[2], 5.0); } + +const char* mc_position_tex_fs = R"(#version 150 + +uniform sampler2D Sampler0; + +uniform vec4 ColorModulator; + +in vec2 texCoord0; + +out vec4 fragColor; + +void main() { + vec4 color = texture(Sampler0, texCoord0); + if (color.a == 0.0) { + discard; + } + fragColor = color * ColorModulator; +} +)"; + +const char* mc_position_tex_vs = R"(#version 150 + +in vec3 Position; +in vec2 UV0; + +uniform mat4 ModelViewMat; +uniform mat4 ProjMat; + +out vec2 texCoord0; + +void main() { + gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0); + + texCoord0 = UV0; +} +)"; + +TEST_F(ProgramTest, MinecraftPositionTex) { + char infoLog[1024] = ""; + + GLuint vs = CreateShader(GL_VERTEX_SHADER); + ShaderSource(vs, 1, &mc_position_tex_vs, NULL); + CompileShader(vs); + GLint vsStatus = GL_FALSE; + GetShaderiv(vs, GL_COMPILE_STATUS, &vsStatus); + GetShaderInfoLog(vs, 1024, nullptr, infoLog); + ASSERT_EQ(vsStatus, GL_TRUE) << infoLog; + + GLuint fs = CreateShader(GL_FRAGMENT_SHADER); + ShaderSource(fs, 1, &mc_position_tex_fs, NULL); + CompileShader(fs); + GLint fsStatus = GL_FALSE; + GetShaderiv(fs, GL_COMPILE_STATUS, &fsStatus); + GetShaderInfoLog(fs, 1024, nullptr, infoLog); + ASSERT_EQ(fsStatus, GL_TRUE) << infoLog; + + GLuint program = CreateProgram(); + AttachShader(program, vs); + AttachShader(program, fs); + + LinkProgram(program); + + UseProgram(program); + + int uniformCount = 0; + GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount); + ASSERT_LT(uniformCount, 4000); + + int sampler0Loc = GetUniformLocation(program, "Sampler0"); + ASSERT_GE(sampler0Loc, 0); + ASSERT_LT(sampler0Loc, 4000); +} From 034aeb9b1202b5a01570624beeaa749f900db3b6 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 27 Oct 2025 11:20:23 +0800 Subject: [PATCH 6/7] [Fix] (MG_State/GL_Program): wrong guard condition in Uniformv_State --- MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp | 2 +- MobileGL/MG_State/GLState/ProgramState/ProgramObject.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index 502c31d2..182e060a 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -473,7 +473,7 @@ namespace MobileGL { return; } - if (location >= programObject->GetUniformCount() || location < -1) { + if (location > programObject->GetMaxUniformLocation() || location < -1) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, MakeShared("MG_Impl/GLImpl", __func__, diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index dcf265b2..5cb84aba 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -25,7 +25,9 @@ namespace MobileGL { Uint GetMaxUniformLocation() const { return m_maxUniformLocation; } Int GetUniformLocation(const String& name) { const auto it = m_uniformLocations.find(name); - return (it == m_uniformLocations.end()) ? -1 : (Int)it->second; + if (it == m_uniformLocations.end()) + return -1; + return (Int)it->second; } GLenum GetUniformType(Uint index) const { return m_uniformTypes[index]; } From 47ea1788dbaa5e6d946e4fea46e28afecfe5b239 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Mon, 27 Oct 2025 12:03:05 +0800 Subject: [PATCH 7/7] [Chore] (All): Format code. --- MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp | 5 ++--- MobileGL/MG_State/GLState/ProgramState/ProgramObject.h | 3 +-- scripts/format_code.sh | 0 3 files changed, 3 insertions(+), 5 deletions(-) mode change 100644 => 100755 scripts/format_code.sh diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index ade6c8cb..67a8a98d 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -114,11 +114,10 @@ namespace MobileGL { } SizeT locNeedle = 0; - for (auto index: unallocatedUniformIndex) { + for (auto index : unallocatedUniformIndex) { auto& uniform = m_program->getUniform(index); for (; locNeedle <= m_maxUniformLocation; locNeedle++) { - if (m_uniformTypes[locNeedle] != GL_ZERO) - continue; + if (m_uniformTypes[locNeedle] != GL_ZERO) continue; // Found a vacant location at locNeedle m_uniformNames[locNeedle] = uniform.name; m_uniformTypes[locNeedle] = uniform.glDefineType; diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index 5cb84aba..fcb47d2b 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -25,8 +25,7 @@ namespace MobileGL { Uint GetMaxUniformLocation() const { return m_maxUniformLocation; } Int GetUniformLocation(const String& name) { const auto it = m_uniformLocations.find(name); - if (it == m_uniformLocations.end()) - return -1; + if (it == m_uniformLocations.end()) return -1; return (Int)it->second; } GLenum GetUniformType(Uint index) const { return m_uniformTypes[index]; } diff --git a/scripts/format_code.sh b/scripts/format_code.sh old mode 100644 new mode 100755