[Feat] (MG_Impl/Framebuffer): Implement renderbuffer funcs.

This commit is contained in:
BZLZHH
2025-12-14 11:28:02 +08:00
parent 69a7374b51
commit 9ab001bf75
5 changed files with 204 additions and 12 deletions
@@ -118,7 +118,7 @@ DECLARE_GL_FUNCTION_HEAD(void, GetFramebufferAttachmentParameteriv, GLenum targe
DECLARE_GL_FUNCTION_HEAD(void, GetIntegerv, GLenum pname, GLint* data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetIntegerv, pname, data)
DECLARE_GL_FUNCTION_HEAD(void, GetProgramiv, GLuint program, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetProgramiv, program, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetProgramInfoLog, program, bufSize, length, infoLog)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetRenderbufferParameteriv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetRenderbufferParameteriv, target, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GetShaderiv, GLuint shader, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetShaderiv, shader, pname, params)
DECLARE_GL_FUNCTION_HEAD(void, GetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetShaderInfoLog, shader, bufSize, length, infoLog)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetShaderPrecisionFormat, shadertype, precisiontype, range, precision)
@@ -1,9 +1,11 @@
#include "GL_Framebuffer.h"
#include "Validators.h"
#include "Config.h"
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
#include <MG_Impl/GLImpl/Texture/Validators.h>
#include <MG_State/GLState/ErrorState/Error.h>
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
#include <MG_Util/Converters/GLToMG/FramebufferEnumConverter.h>
#if MOBILEGL_BACKEND == MOBILEGL_BACKEND_TYPE_DIRECT_GLES
#include <MG_Backend/DirectGLES/DirectGLES.h>
@@ -29,17 +31,34 @@ namespace MobileGL {
}
void RenderbufferStorage_State(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
// TODO: implement
RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target);
if (!FramebufferImpl::ValidateRenderbufferTarget(rbTarget)) return;
auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(rbTarget);
auto renderbufferObject = bindingSlot.GetBoundObject();
if (!renderbufferObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "RenderbufferStorage_State",
"Renderbuffer target is bound to no renderbuffer object."));
return;
}
TextureInternalFormat format = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
if (!TextureImpl::ValidateTextureInternalFormat(format)) return;
if (width < 0 || height < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "RenderbufferStorage_State",
"Width and height must be non-negative."));
return;
}
renderbufferObject->AllocateStorage({width, height});
}
GLboolean IsRenderbuffer_State(GLuint renderbuffer) {
// TODO: implement
return GL_FALSE;
return MG_State::pGLContext->ValidateRenderbufferName(renderbuffer);
}
GLboolean IsFramebuffer_State(GLuint framebuffer) {
// TODO: implement
return GL_FALSE;
return MG_State::pGLContext->ValidateFramebufferName(framebuffer);
}
void GetFramebufferAttachmentParameteriv_State(GLenum target, GLenum attachment, GLenum pname, GLint* params) {
@@ -53,7 +72,14 @@ namespace MobileGL {
}
void GenRenderbuffers_State(GLsizei n, GLuint* renderbuffers) {
// TODO: implement
if (n < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GenRenderbuffers_State", "n must be non-negative"));
return;
}
auto renderbufferNames = MG_State::pGLContext->GenRenderbufferNames(n);
Memcpy(renderbuffers, renderbufferNames.data(), sizeof(GLuint) * static_cast<SizeT>(n));
}
void GenFramebuffers_State(GLsizei n, GLuint* framebuffers) {
@@ -64,7 +90,7 @@ namespace MobileGL {
return;
}
auto framebuffersNames = MG_State::pGLContext->GenFramebufferNames(n);
Copy(framebuffersNames.data(), framebuffers, framebuffersNames.size());
Memcpy(framebuffers, framebuffersNames.data(), sizeof(GLuint) * static_cast<SizeT>(n));
}
void FramebufferTextureLayer_State(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
@@ -132,7 +158,41 @@ namespace MobileGL {
void FramebufferRenderbuffer_State(GLenum target, GLenum attachment, GLenum renderbuffertarget,
GLuint renderbuffer) {
// TODO: implement
if (target == GL_FRAMEBUFFER) {
target = GL_DRAW_FRAMEBUFFER;
}
FramebufferAttachmentType attachmentType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(attachment);
FramebufferTarget framebufferTarget = MG_Util::ConvertGLEnumToFramebufferTarget(target);
RenderbufferTarget rbTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(renderbuffertarget);
if (!FramebufferImpl::ValidateFramebufferAttachmentType(attachmentType)) return;
if (!FramebufferImpl::ValidateFramebufferTarget(framebufferTarget)) return;
if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return;
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(framebufferTarget);
auto framebufferObject = bindingSlot.GetBoundObject();
if (!framebufferObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferRenderbuffer_State",
"Framebuffer target is bound to no framebuffer object."));
return;
}
if (renderbuffer == 0) {
framebufferObject->Detach(attachmentType);
return;
}
auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer);
if (!renderbufferObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "FramebufferRenderbuffer_State",
std::format("Renderbuffer object {} is not valid.", renderbuffer)));
return;
}
framebufferObject->AttachRenderbuffer(attachmentType, renderbufferObject);
}
void DrawBuffers_State(GLsizei n, const GLenum* bufs) {
@@ -227,7 +287,26 @@ namespace MobileGL {
}
void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) {
// TODO: implement
if (n < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteRenderbuffers_State",
"n must be non-negative."));
return;
}
if (!renderbuffers) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteRenderbuffers_State",
"Renderbuffer names array cannot be null."));
return;
}
for (SizeT i = 0; i < static_cast<SizeT>(n); ++i) {
Uint bufferName = renderbuffers[i];
if (bufferName == 0) continue;
if (!FramebufferImpl::ValidateRenderbufferName(bufferName)) continue;
MG_State::pGLContext->MarkRenderbufferObjectForDeletion(bufferName);
}
}
void DeleteFramebuffers_State(GLsizei n, const GLuint* framebuffers) {
@@ -276,7 +355,18 @@ namespace MobileGL {
}
void BindRenderbuffer_State(GLenum target, GLuint renderbuffer) {
// TODO: implement
if (!FramebufferImpl::ValidateRenderbufferName(renderbuffer)) return;
RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target);
if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return;
auto renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer);
if (!renderbufferObject) {
MG_State::pGLContext->CreateRenderbufferObject(renderbuffer);
renderbufferObject = MG_State::pGLContext->GetRenderbufferObject(renderbuffer);
}
auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget);
bindingSlot.Bind(renderbufferObject);
}
void BindFramebuffer_State(GLenum target, GLuint framebuffer) {
@@ -300,6 +390,62 @@ namespace MobileGL {
bindingSlot.Bind(framebufferObject);
}
void GetRenderbufferParameteriv_State(GLenum target, GLenum pname, GLint* params) {
if (!params) return;
RenderbufferTarget renderbufferTarget = MG_Util::ConvertGLEnumToRenderbufferTarget(target);
if (!FramebufferImpl::ValidateRenderbufferTarget(renderbufferTarget)) return;
auto& bindingSlot = MG_State::pGLContext->GetRenderbufferBindingSlot(renderbufferTarget);
auto renderbufferObject = bindingSlot.GetBoundObject();
if (!renderbufferObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GetRenderbufferParameteriv_State",
"Renderbuffer target is bound to no renderbuffer object."));
return;
}
switch (pname) {
case GL_RENDERBUFFER_WIDTH:
*params = static_cast<GLint>(renderbufferObject->GetWidth());
break;
case GL_RENDERBUFFER_HEIGHT:
*params = static_cast<GLint>(renderbufferObject->GetHeight());
break;
case GL_RENDERBUFFER_INTERNAL_FORMAT:
*params = MG_Util::ConvertTextureInternalFormatToGLEnum(renderbufferObject->GetInternalFormat());
break;
case GL_RENDERBUFFER_RED_SIZE:
*params = static_cast<GLint>(renderbufferObject->GetRedSize());
break;
case GL_RENDERBUFFER_GREEN_SIZE:
*params = static_cast<GLint>(renderbufferObject->GetGreenSize());
break;
case GL_RENDERBUFFER_BLUE_SIZE:
*params = static_cast<GLint>(renderbufferObject->GetBlueSize());
break;
case GL_RENDERBUFFER_ALPHA_SIZE:
*params = static_cast<GLint>(renderbufferObject->GetAlphaSize());
break;
case GL_RENDERBUFFER_DEPTH_SIZE:
*params = static_cast<GLint>(renderbufferObject->GetDepthSize());
break;
case GL_RENDERBUFFER_STENCIL_SIZE:
*params = static_cast<GLint>(renderbufferObject->GetStencilSize());
break;
case GL_RENDERBUFFER_SAMPLES:
*params = static_cast<GLint>(renderbufferObject->GetSamples());
break;
default:
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", "GetRenderbufferParameteriv_State",
std::format("pname %s is not an accepted value.", MG_Util::ConvertGLEnumToString(pname))));
return;
}
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
void SampleMaski(GLuint maskNumber, GLbitfield mask) {
SampleMaski_State(maskNumber, mask);
@@ -392,6 +538,10 @@ namespace MobileGL {
BindFramebuffer_State(target, framebuffer);
}
void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) {
GetRenderbufferParameteriv_State(target, pname, params);
}
namespace FramebufferImpl {
DefaultFramebufferInfo* pDefaultFramebufferInfo;
}
@@ -6,6 +6,14 @@
namespace MobileGL {
namespace MG_Impl::GLImpl {
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
GLboolean IsRenderbuffer(GLuint renderbuffer);
void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
void BindRenderbuffer(GLenum target, GLuint renderbuffer);
void SampleMaski(GLuint maskNumber, GLbitfield mask);
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height);
@@ -53,5 +53,37 @@ namespace MobileGL::MG_Impl::GLImpl {
}
return true;
}
Bool ValidateRenderbufferTarget(RenderbufferTarget target) {
if (target == RenderbufferTarget::Unknown) {
using namespace MG_Util;
String renderbufferTargetStr = ConvertRenderbufferTargetToString(target);
String glTargetStr = ConvertGLEnumToString(ConvertRenderbufferTargetToGLEnum(target));
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferTarget",
std::format("Target {} ({}) is not valid.", renderbufferTargetStr, glTargetStr)));
return false;
}
return true;
}
Bool ValidateRenderbufferName(Uint index, Bool allowZero) {
if (index == 0 && !allowZero) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferName",
"Renderbuffer name 0 is not valid in this situation."));
return false;
}
Bool isValid = MG_State::pGLContext->ValidateRenderbufferName(index);
if (isValid) return true;
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl/FramebufferImpl", "ValidateRenderbufferName",
std::format("Renderbuffer name {} is not valid.", index)));
return false;
}
} // namespace FramebufferImpl
} // namespace MobileGL::MG_Impl::GLImpl
@@ -7,5 +7,7 @@ namespace MobileGL::MG_Impl::GLImpl {
Bool ValidateFramebufferTarget(FramebufferTarget target);
Bool ValidateFramebufferName(Uint index, Bool allowZero = true);
Bool ValidateFramebufferAttachmentType(FramebufferAttachmentType attachment);
Bool ValidateRenderbufferTarget(RenderbufferTarget target);
Bool ValidateRenderbufferName(Uint index, Bool allowZero = true);
} // namespace FramebufferImpl
} // namespace MobileGL::MG_Impl::GLImpl