mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Feat] (MG_State/Framebuffer, MG_Impl/Framebuffer): implement glDrawBuffers in the state machine
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include "GL_Framebuffer.h"
|
#include "GL_Framebuffer.h"
|
||||||
#include "Validators.h"
|
#include "Validators.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
|
||||||
#include <MG_Impl/GLImpl/Texture/Validators.h>
|
#include <MG_Impl/GLImpl/Texture/Validators.h>
|
||||||
#include <MG_State/GLState/ErrorState/Error.h>
|
#include <MG_State/GLState/ErrorState/Error.h>
|
||||||
#include <MG_Util/Converters/GLToMG/FramebufferEnumConverter.h>
|
#include <MG_Util/Converters/GLToMG/FramebufferEnumConverter.h>
|
||||||
@@ -133,7 +134,76 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DrawBuffers_State(GLsizei n, const GLenum* bufs) {
|
void DrawBuffers_State(GLsizei n, const GLenum* bufs) {
|
||||||
// TODO: implement
|
if (n < 0) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`n` is less than 0."));
|
||||||
|
return;
|
||||||
|
} else if (n > MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`n` is greater than `GL_MAX_DRAW_BUFFERS`."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get bound framebuffer
|
||||||
|
auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw);
|
||||||
|
auto fbo = bindingSlot.GetBoundObject();
|
||||||
|
bool isDefaultFBO = (fbo == FramebufferImpl::pDefaultFramebufferInfo->defaultFBO);
|
||||||
|
|
||||||
|
static int existenceMap[(SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount] = {
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
std::fill(existenceMap, existenceMap + (SizeT)FramebufferAttachmentType::FramebufferAttachmentTypeCount, -1);
|
||||||
|
|
||||||
|
for (GLsizei i = 0; i < n; ++i) {
|
||||||
|
auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(bufs[i]);
|
||||||
|
|
||||||
|
// ------------------- Check validity begin ------------------------
|
||||||
|
if (attType == FramebufferAttachmentType::Unknown) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::format("bufs[{}] = %s is not an accepted value.", i, MG_Util::ConvertGLEnumToString(bufs[i]))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDefaultFBO &&
|
||||||
|
attType >= FramebufferAttachmentType::Color0 && attType <= FramebufferAttachmentType::Color31) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::format("FBO is default FBO, but bufs[{}] = {} is one of the `GL_COLOR_ATTACHMENTn` tokens.", i, MG_Util::ConvertGLEnumToString(bufs[i]))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDefaultFBO &&
|
||||||
|
attType >= FramebufferAttachmentType::FrontLeft && attType <= FramebufferAttachmentType::BackRight) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::format("FBO is not default FBO, but bufs[{}] = {} is anything other than `GL_NONE` or one of the `GL_COLOR_ATTACHMENTn` tokens.", i, MG_Util::ConvertGLEnumToString(bufs[i]))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attType != FramebufferAttachmentType::None && existenceMap[(SizeT)attType] >= 0) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::format("a symbolic constant other than `GL_NONE` appears more than once in bufs. bufs[{}] == bufs[{}] == {}.", i, existenceMap[(SizeT)attType], MG_Util::ConvertGLEnumToString(bufs[i]))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
existenceMap[(SizeT)attType] = i;
|
||||||
|
|
||||||
|
if ((SizeT)attType > (SizeT)FramebufferAttachmentType::Color0 + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
std::format("bufs[{}] == {} indicates a color buffer that does not exist in the current GL context.", i, MG_Util::ConvertGLEnumToString(bufs[i]))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ------------------------- Check validity end ----------------------------------
|
||||||
|
fbo->SetDrawBuffer(i, attType);
|
||||||
|
}
|
||||||
|
for (GLsizei i = n; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
||||||
|
fbo->SetDrawBuffer(i, FramebufferAttachmentType::None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) {
|
void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) {
|
||||||
|
|||||||
@@ -63,8 +63,10 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FramebufferObject
|
// FramebufferObject
|
||||||
FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {
|
FramebufferObject::FramebufferObject(Uint externalIndex) :
|
||||||
|
m_externalIndex(externalIndex) {
|
||||||
m_attachments.fill(FramebufferAttachment(false));
|
m_attachments.fill(FramebufferAttachment(false));
|
||||||
|
m_drawBuffers.fill(FramebufferAttachmentType::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
|
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
|
||||||
@@ -126,12 +128,22 @@ namespace MobileGL {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferObject::SetDrawBuffers(const std::vector<FramebufferAttachmentType>& buffers) {
|
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
|
||||||
m_drawBuffers = buffers;
|
if (m_drawBuffers[index] == buffer)
|
||||||
|
return;
|
||||||
m_drawBuffersDirty = true;
|
m_drawBuffersDirty = true;
|
||||||
|
m_drawBuffers[index] = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector<FramebufferAttachmentType>& FramebufferObject::GetDrawBuffers() const {
|
// void FramebufferObject::SetDrawBuffers(const Vector<FramebufferAttachmentType>& buffers) {
|
||||||
|
// m_drawBuffers = buffers;
|
||||||
|
// m_drawBuffersDirty = true;
|
||||||
|
// }
|
||||||
|
// void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
const auto& FramebufferObject::GetDrawBuffers() const {
|
||||||
return m_drawBuffers;
|
return m_drawBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,16 @@ namespace MobileGL {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class FramebufferAttachmentType {
|
enum class FramebufferAttachmentType {
|
||||||
|
None,
|
||||||
|
|
||||||
|
FrontLeft,
|
||||||
|
FrontRight,
|
||||||
|
BackLeft,
|
||||||
|
BackRight,
|
||||||
|
|
||||||
|
Depth,
|
||||||
|
Stencil,
|
||||||
|
|
||||||
Color0,
|
Color0,
|
||||||
Color1,
|
Color1,
|
||||||
Color2,
|
Color2,
|
||||||
@@ -44,8 +54,7 @@ namespace MobileGL {
|
|||||||
Color29,
|
Color29,
|
||||||
Color30,
|
Color30,
|
||||||
Color31,
|
Color31,
|
||||||
Depth,
|
|
||||||
Stencil,
|
|
||||||
FramebufferAttachmentTypeCount,
|
FramebufferAttachmentTypeCount,
|
||||||
Unknown = -1
|
Unknown = -1
|
||||||
};
|
};
|
||||||
@@ -81,6 +90,7 @@ namespace MobileGL {
|
|||||||
class FramebufferObject {
|
class FramebufferObject {
|
||||||
public:
|
public:
|
||||||
using TargetEnum = FramebufferTarget;
|
using TargetEnum = FramebufferTarget;
|
||||||
|
static constexpr uint MAX_DRAW_BUFFERS = 8;
|
||||||
|
|
||||||
FramebufferObject(Uint externalIndex);
|
FramebufferObject(Uint externalIndex);
|
||||||
|
|
||||||
@@ -93,8 +103,9 @@ namespace MobileGL {
|
|||||||
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>&
|
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>&
|
||||||
GetAllAttachments() const;
|
GetAllAttachments() const;
|
||||||
Bool CheckCompleteness() const;
|
Bool CheckCompleteness() const;
|
||||||
void SetDrawBuffers(const std::vector<FramebufferAttachmentType>& buffers);
|
// void SetDrawBuffers(const Vector<FramebufferAttachmentType>& buffers);
|
||||||
const Vector<FramebufferAttachmentType>& GetDrawBuffers() const;
|
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
|
||||||
|
const auto& GetDrawBuffers() const;
|
||||||
Uint GetExternalIndex() const;
|
Uint GetExternalIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -103,7 +114,7 @@ namespace MobileGL {
|
|||||||
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>
|
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>
|
||||||
m_attachments;
|
m_attachments;
|
||||||
Bool m_drawBuffersDirty = true;
|
Bool m_drawBuffersDirty = true;
|
||||||
Vector<FramebufferAttachmentType> m_drawBuffers;
|
Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS> m_drawBuffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
|
|||||||
Reference in New Issue
Block a user