From 7debcd79278fa400afe2c4154d3dc853753a4ed2 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 17 May 2025 10:25:58 +0800 Subject: [PATCH] [Feat] (Getter): Implement GetIntegerv. --- .../Implementations/GL/Getter/GL_Getter.cpp | 188 ++++++++++++++++-- MG/MG_GL/State/Texture/TextureState.h | 2 +- 2 files changed, 167 insertions(+), 23 deletions(-) diff --git a/MG/MG_GL/Implementations/GL/Getter/GL_Getter.cpp b/MG/MG_GL/Implementations/GL/Getter/GL_Getter.cpp index f5d19256..e2b920a7 100644 --- a/MG/MG_GL/Implementations/GL/Getter/GL_Getter.cpp +++ b/MG/MG_GL/Implementations/GL/Getter/GL_Getter.cpp @@ -114,37 +114,181 @@ namespace MG_GL::GL { void GetIntegerv(GLenum pname, GLint *params) { MG_Util::Debug::LogD("glGetIntegerv, pname: %s", MG_Util::Debug::GLEnumToString(pname)); + if (!params) { + MG_State::SetError(GL_INVALID_VALUE); + return; + } + switch (pname) { - case GL_CONTEXT_PROFILE_MASK: - (*params) = GL_CONTEXT_CORE_PROFILE_BIT; + // Viewport and scissor + case GL_VIEWPORT: + memcpy(params, MG_State_T::commonState->viewport, 4 * sizeof(GLint)); break; - case GL_NUM_EXTENSIONS: - static GLint num_extensions = -1; - if (num_extensions == -1) { - const GLubyte* ext_str = MG_GL::GL::GetString(GL_EXTENSIONS); - char *copy = strdup((const char *) ext_str); - char *token = strtok(copy, " "); - num_extensions = 0; - while (token) { - num_extensions++; - token = strtok(nullptr, " "); - } - free(copy); - } - (*params) = num_extensions; + case GL_SCISSOR_BOX: + // TODO: memcpy(params, MG_State_T::commonState->scissorBox, 4 * sizeof(GLint)); break; - case GL_MAJOR_VERSION: - (*params) = MG_Global::GL::GLVersionMajor; + case GL_MAX_VIEWPORT_DIMS: { + static const GLint maxDims[2] = {16384, 16384}; + memcpy(params, maxDims, sizeof(maxDims)); break; - case GL_MINOR_VERSION: - (*params) = MG_Global::GL::GLVersionMinor; + } + + // Buffer bindings + case GL_ARRAY_BUFFER_BINDING: + params[0] = static_cast(MG_State_T::bufferState->GetCurrentBinding(GL_ARRAY_BUFFER)); + break; + + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + params[0] = static_cast(MG_State_T::vertexArrayState->GetBoundElementBuffer()); + break; + case GL_DRAW_FRAMEBUFFER_BINDING: + params[0] = static_cast(MG_State_T::framebufferState->currentBindings_[GL_DRAW_FRAMEBUFFER]); + break; + case GL_READ_FRAMEBUFFER_BINDING: + params[0] = static_cast(MG_State_T::framebufferState->currentBindings_[GL_READ_FRAMEBUFFER]); + break; + case GL_RENDERBUFFER_BINDING: + // TODO: params[0] = static_cast(MG_State_T::framebufferState->currentRenderbuffer_); + break; + + // Program state + case GL_CURRENT_PROGRAM: + params[0] = static_cast(MG_State_T::programState->currentProgram_); + break; + case GL_MAX_VERTEX_ATTRIBS: + // TODO: Check the real value + params[0] = 64; + break; + + // Texture state + case GL_TEXTURE_BINDING_2D: { + GLuint unit = MG_State_T::textureState->activeTextureUnit_; + auto& textures = MG_State_T::textureState->textureUnits_[unit].boundTextures; + params[0] = textures.count(GL_TEXTURE_2D) ? static_cast(textures[GL_TEXTURE_2D]) : 0; + break; + } + case GL_ACTIVE_TEXTURE: + params[0] = GL_TEXTURE0 + MG_State_T::textureState->activeTextureUnit_; break; case GL_MAX_TEXTURE_SIZE: - // TODO: Get real GL_MAX_TEXTURE_SIZE. - (*params) = 65535; + params[0] = 8192; break; + + // Blend state + case GL_BLEND_SRC_RGB: + params[0] = static_cast(MG_State_T::commonState->blendSrcRGB); + break; + case GL_BLEND_DST_RGB: + params[0] = static_cast(MG_State_T::commonState->blendDstRGB); + break; + case GL_BLEND_SRC_ALPHA: + params[0] = static_cast(MG_State_T::commonState->blendSrcAlpha); + break; + case GL_BLEND_DST_ALPHA: + params[0] = static_cast(MG_State_T::commonState->blendDstAlpha); + break; + + // Depth and stencil + case GL_DEPTH_FUNC: + params[0] = static_cast(MG_State_T::commonState->depthFunc); + break; + case GL_DEPTH_WRITEMASK: + params[0] = static_cast(MG_State_T::commonState->depthMask); + break; + case GL_STENCIL_REF: + // TODO: params[0] = MG_State_T::commonState->stencilRef; + break; + + // Capability enables + case GL_BLEND: + params[0] = MG_State_T::commonState->capabilities[GL_BLEND] ? GL_TRUE : GL_FALSE; + break; + case GL_DEPTH_TEST: + params[0] = MG_State_T::commonState->capabilities[GL_DEPTH_TEST] ? GL_TRUE : GL_FALSE; + break; + case GL_SCISSOR_TEST: + params[0] = MG_State_T::commonState->capabilities[GL_SCISSOR_TEST] ? GL_TRUE : GL_FALSE; + break; + + // Pixel operations + case GL_PACK_ALIGNMENT: + params[0] = MG_State_T::commonState->QueryPixelStoreInt(GL_PACK_ALIGNMENT); + break; + case GL_UNPACK_ALIGNMENT: + params[0] = MG_State_T::commonState->QueryPixelStoreInt(GL_UNPACK_ALIGNMENT); + break; + + // Hardware limits, TODO: Check the real values + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + params[0] = 32; + break; + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + params[0] = 32; + break; + case GL_MAX_TEXTURE_IMAGE_UNITS: + params[0] = 32; + break; + case GL_MAX_RENDERBUFFER_SIZE: + params[0] = 65537; + break; + case GL_MAX_DRAW_BUFFERS: + params[0] = 32; + break; + case GL_MAX_COLOR_ATTACHMENTS: + params[0] = 32; + break; + + // Color state + case GL_COLOR_CLEAR_VALUE: { + const auto& c = MG_State_T::commonState->clearColor; + params[0] = static_cast(c[0] * 0x7FFF); + params[1] = static_cast(c[1] * 0x7FFF); + params[2] = static_cast(c[2] * 0x7FFF); + params[3] = static_cast(c[3] * 0x7FFF); + break; + } + case GL_COLOR_WRITEMASK: + params[0] = MG_State_T::commonState->colorMask[0]; + params[1] = MG_State_T::commonState->colorMask[1]; + params[2] = MG_State_T::commonState->colorMask[2]; + params[3] = MG_State_T::commonState->colorMask[3]; + break; + + // Stencil operations + case GL_STENCIL_CLEAR_VALUE: + // TODO: params[0] = MG_State_T::commonState->stencilClearValue; + break; + case GL_STENCIL_BITS: + // TODO: Check the real value + params[0] = 8; + break; + + // Implementation limits + case GL_SUBPIXEL_BITS: + // TODO: Check the real value + params[0] = 4; + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + // TODO: params[0] = static_cast(MG_State_T::textureState->compressedFormats_.size()); + break; + case GL_COMPRESSED_TEXTURE_FORMATS: + // TODO: Implement GL_COMPRESSED_TEXTURE_FORMATS + break; + + // Polygon state + case GL_POLYGON_OFFSET_FACTOR: + // TODO: params[0] = static_cast(MG_State_T::commonState->polygonOffsetFactor); + break; + case GL_POLYGON_OFFSET_UNITS: + // TODO: params[0] = static_cast(MG_State_T::commonState->polygonOffsetUnits); + break; + + // Others... default: + MG_Util::Debug::LogE("glGetIntegerv: Invalid enum %s (0x%X)", MG_Util::Debug::GLEnumToString(pname), pname); + MG_State::SetError(GL_INVALID_ENUM); break; } } + } \ No newline at end of file diff --git a/MG/MG_GL/State/Texture/TextureState.h b/MG/MG_GL/State/Texture/TextureState.h index ea0de3af..acf23e63 100644 --- a/MG/MG_GL/State/Texture/TextureState.h +++ b/MG/MG_GL/State/Texture/TextureState.h @@ -62,7 +62,6 @@ class TextureState { template using unordered_map = ankerl::unordered_dense::map; private: - GLuint activeTextureUnit_ = 0; GLuint lastUsedID_ = 1; // std::unordered_set freeIDs_; @@ -96,6 +95,7 @@ public: GLenum QueryLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params); std::vector textureUnits_; + GLuint activeTextureUnit_ = 0; private: size_t CalculatePixelDataSize_(GLenum format, GLenum type, GLsizei width, GLsizei height); void InvalidateTextureInAllUnits_(GLuint texture);