mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 05:38:31 +09:00
[Feat] (MG_Impl/GLImpl, MG_State): implement glClampColor and glPolygonMode
Fill the two empty // TODO state handlers with GL 3.3 Core-conformant behavior, backed by new RenderState fields and glGet* read-back. glClampColor: - Accept only GL_CLAMP_READ_COLOR (compat GL_CLAMP_VERTEX/FRAGMENT_COLOR rejected); clamp is one of GL_TRUE / GL_FALSE / GL_FIXED_ONLY. Note the Khronos man page wrongly omits GL_FIXED_ONLY from the accepted set, but it is legal AND the default, so it is accepted here. - Default GL_FIXED_ONLY; both error paths are GL_INVALID_ENUM with no state change. glGetIntegerv returns the raw tri-state enum; GetFloatv/ GetDoublev widen it and GetBooleanv converts nonzero to GL_TRUE via the existing fall-through, so one GetIntegerv case serves every getter. glPolygonMode: - Core accepts only face == GL_FRONT_AND_BACK (GL_FRONT/GL_BACK were removed in 3.1 core); mode is GL_POINT / GL_LINE / GL_FILL. Both errors are GL_INVALID_ENUM with no state change. - Keep separate front/back slots so GL_POLYGON_MODE round-trips its two values (identical under a core context). The raster effect (VkPolygonMode + fillModeNonSolid) remains a backend follow-up; this is the state layer. Tests: two RenderStateSanity round-trips; the glClampColor GL_FIXED_ONLY acceptance assertion is mutation-verified (rejecting it fails the test). Full SanityTest sweep green (29/29).
This commit is contained in:
@@ -952,6 +952,12 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
*params = static_cast<GLint>(MG_Util::ConvertBlendFactorToGLEnum(srcRGB));
|
||||
return;
|
||||
}
|
||||
case GL_CLAMP_READ_COLOR:
|
||||
// Tri-state enum (GL_TRUE / GL_FALSE / GL_FIXED_ONLY). glGetIntegerv returns the raw
|
||||
// enum; GetFloatv/GetDoublev widen it and GetBooleanv converts nonzero to GL_TRUE, so
|
||||
// this single case serves every getter flavor.
|
||||
*params = static_cast<GLint>(MG_State::pGLContext->GetClampReadColor());
|
||||
return;
|
||||
case GL_COLOR_CLEAR_VALUE: {
|
||||
const FloatVec4& clearColor = MG_State::pGLContext->GetClearColor();
|
||||
params[0] = static_cast<GLint>(clearColor.x());
|
||||
@@ -1364,8 +1370,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
*params = static_cast<GLint>(MG_State::pGLContext->GetPointSize());
|
||||
return;
|
||||
case GL_POLYGON_MODE:
|
||||
params[0] = GL_FILL;
|
||||
params[1] = GL_FILL;
|
||||
params[0] = static_cast<GLint>(MG_State::pGLContext->GetPolygonModeFront());
|
||||
params[1] = static_cast<GLint>(MG_State::pGLContext->GetPolygonModeBack());
|
||||
return;
|
||||
case GL_POLYGON_OFFSET_FACTOR:
|
||||
*params = static_cast<GLint>(MG_State::pGLContext->GetPolygonOffsetFactor());
|
||||
|
||||
@@ -193,7 +193,28 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
|
||||
void PolygonMode_State(GLenum face, GLenum mode) {
|
||||
// TODO: implement
|
||||
// GL 3.3 core: separate front/back polygon modes were removed in 3.1, so the only legal
|
||||
// face is GL_FRONT_AND_BACK. GL_FRONT / GL_BACK must be rejected (some desktop drivers
|
||||
// leniently accept them, but that is non-conformant). Both errors are GL_INVALID_ENUM and
|
||||
// leave state untouched.
|
||||
if (face != GL_FRONT_AND_BACK) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||
"glPolygonMode face must be GL_FRONT_AND_BACK in the core profile; got " +
|
||||
MG_Util::ConvertGLEnumToString(face) + "."));
|
||||
return;
|
||||
}
|
||||
if (mode != GL_POINT && mode != GL_LINE && mode != GL_FILL) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||
"glPolygonMode mode must be GL_POINT, GL_LINE, or GL_FILL; got " +
|
||||
MG_Util::ConvertGLEnumToString(mode) + "."));
|
||||
return;
|
||||
}
|
||||
// Core sets both faces together; keep two slots so GL_POLYGON_MODE round-trips its two values.
|
||||
MG_State::pGLContext->SetPolygonMode(mode, mode);
|
||||
}
|
||||
|
||||
void PointSize_State(GLfloat size) {
|
||||
@@ -503,7 +524,30 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
|
||||
void ClampColor_State(GLenum target, GLenum clamp) {
|
||||
// TODO: implement
|
||||
// GL 3.3 core: the only legal target is GL_CLAMP_READ_COLOR. The compatibility-only
|
||||
// GL_CLAMP_VERTEX_COLOR / GL_CLAMP_FRAGMENT_COLOR were removed from the core profile and
|
||||
// must be rejected.
|
||||
if (target != GL_CLAMP_READ_COLOR) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||
"glClampColor target must be GL_CLAMP_READ_COLOR in the core profile; "
|
||||
"got " +
|
||||
MG_Util::ConvertGLEnumToString(target) + "."));
|
||||
return;
|
||||
}
|
||||
// clamp must be one of GL_TRUE, GL_FALSE, or GL_FIXED_ONLY. NOTE: the Khronos man page's
|
||||
// Errors section wrongly omits GL_FIXED_ONLY, but the spec lists it as legal AND it is the
|
||||
// default value, so it must be accepted here.
|
||||
if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidEnum,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||
"glClampColor clamp must be GL_TRUE, GL_FALSE, or GL_FIXED_ONLY; got " +
|
||||
MG_Util::ConvertGLEnumToString(clamp) + "."));
|
||||
return;
|
||||
}
|
||||
MG_State::pGLContext->SetClampReadColor(clamp);
|
||||
}
|
||||
|
||||
void BlendFuncSeparate_State(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
|
||||
|
||||
Reference in New Issue
Block a user