[Feat] (All): Continue building the basic structure.

Feat: implement MG_Impl/VertexArray
Feat: add tests about MG_Impl/VertexArray
Feat: add several converters
Feat: implement IsBuffer
This commit is contained in:
BZLZHH
2025-07-25 21:36:14 +08:00
parent e7a21423da
commit 47f7039720
18 changed files with 672 additions and 12 deletions
@@ -384,6 +384,13 @@ namespace MobileGL {
auto& bindingSlot = MG_State::pGLContext->GetBufferBindingSlot(bufferTarget);
bindingSlot.Bind(bufferObject);
if (bufferTarget == BufferTarget::Index) {
auto currentVAO = MG_State::pGLContext->GetBoundVertexArray();
if (currentVAO) {
currentVAO->BindElementBuffer(bufferObject);
}
}
}
void GenBuffers_State(GLsizei n, GLuint* buffers) {
@@ -396,7 +403,23 @@ namespace MobileGL {
Copy(bufferNames.data(), buffers, bufferNames.size());
}
GLboolean IsBuffer_State(GLuint buffer) {
if (buffer == 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "IsBuffer_State",
"Buffer name 0 is not a valid buffer object."));
return GL_FALSE;
}
if (!BufferImpl::ValidateBufferName(buffer)) return GL_FALSE;
return MG_State::pGLContext->ValidateBufferObject(buffer) ? GL_TRUE : GL_FALSE;
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
GLboolean IsBuffer(GLuint buffer) {
return IsBuffer_State(buffer);
}
void DeleteBuffers(GLsizei n, const GLuint* buffers) {
DeleteBuffers_State(n, buffers);
}
@@ -3,6 +3,7 @@
namespace MobileGL {
namespace MG_Impl::GLImpl {
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
GLboolean IsBuffer(GLuint buffer);
void DeleteBuffers(GLsizei n, const GLuint* buffers);
void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
GLboolean UnmapBuffer(GLenum target);
@@ -68,11 +68,11 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, DepthMask, GLboolean flag) DECLARE_GL_FUNCTI
DECLARE_GL_FUNCTION_STUB_HEAD(void, DepthRangef, GLfloat n, GLfloat f) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DepthRangef, n, f)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DetachShader, GLuint program, GLuint shader) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DetachShader, program, shader)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Disable, GLenum cap) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Disable, cap)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DisableVertexAttribArray, GLuint index) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DisableVertexAttribArray, index)
DECLARE_GL_FUNCTION_HEAD(void, DisableVertexAttribArray, GLuint index) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DisableVertexAttribArray, index)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawArrays, GLenum mode, GLint first, GLsizei count) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawArrays, mode, first, count)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawElements, GLenum mode, GLsizei count, GLenum type, const void* indices) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawElements, mode, count, type, indices)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Enable, GLenum cap) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Enable, cap)
DECLARE_GL_FUNCTION_STUB_HEAD(void, EnableVertexAttribArray, GLuint index) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EnableVertexAttribArray, index)
DECLARE_GL_FUNCTION_HEAD(void, EnableVertexAttribArray, GLuint index) DECLARE_GL_FUNCTION_END_NO_RETURN(void, EnableVertexAttribArray, index)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Finish) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Finish)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Flush) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Flush)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer)
@@ -109,7 +109,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribfv, GLuint index, GLenum pnam
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribiv, GLuint index, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexAttribiv, index, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexAttribPointerv, index, pname, pointer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Hint, GLenum target, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Hint, target, mode)
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsBuffer, GLuint buffer) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsBuffer, buffer)
DECLARE_GL_FUNCTION_HEAD(GLboolean, IsBuffer, GLuint buffer) DECLARE_GL_FUNCTION_END(GLboolean, IsBuffer, buffer)
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsEnabled, GLenum cap) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsEnabled, cap)
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsFramebuffer, GLuint framebuffer) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsFramebuffer, framebuffer)
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsProgram, GLuint program) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsProgram, program)
@@ -168,7 +168,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib3f, GLuint index, GLfloat x, GLf
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib3fv, GLuint index, const GLfloat* v) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttrib3fv, index, v)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib4f, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttrib4f, index, x, y, z, w)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttrib4fv, GLuint index, const GLfloat* v) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttrib4fv, index, v)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttribPointer, index, size, type, normalized, stride, pointer)
DECLARE_GL_FUNCTION_HEAD(void, VertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, VertexAttribPointer, index, size, type, normalized, stride, pointer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, Viewport, GLint x, GLint y, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Viewport, x, y, width, height)
DECLARE_GL_FUNCTION_STUB_HEAD(void, ReadBuffer, GLenum src) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ReadBuffer, src)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawRangeElements, mode, start, end, count, type, indices)
@@ -198,10 +198,10 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BlitFramebuffer, GLint srcX0, GLint srcY0, G
DECLARE_GL_FUNCTION_STUB_HEAD(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, RenderbufferStorageMultisample, target, samples, internalformat, width, height)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FramebufferTextureLayer, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FramebufferTextureLayer, target, attachment, texture, level, layer)
DECLARE_GL_FUNCTION_HEAD(void, FlushMappedBufferRange, GLenum target, GLintptr offset, GLsizeiptr length) DECLARE_GL_FUNCTION_END_NO_RETURN(void, FlushMappedBufferRange, target, offset, length)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BindVertexArray, GLuint array) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindVertexArray, array)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteVertexArrays, GLsizei n, const GLuint* arrays) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteVertexArrays, n, arrays)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GenVertexArrays, GLsizei n, GLuint* arrays) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GenVertexArrays, n, arrays)
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsVertexArray, GLuint array) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsVertexArray, array)
DECLARE_GL_FUNCTION_HEAD(void, BindVertexArray, GLuint array) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindVertexArray, array)
DECLARE_GL_FUNCTION_HEAD(void, DeleteVertexArrays, GLsizei n, const GLuint* arrays) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DeleteVertexArrays, n, arrays)
DECLARE_GL_FUNCTION_HEAD(void, GenVertexArrays, GLsizei n, GLuint* arrays) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GenVertexArrays, n, arrays)
DECLARE_GL_FUNCTION_HEAD(GLboolean, IsVertexArray, GLuint array) DECLARE_GL_FUNCTION_END(GLboolean, IsVertexArray, array)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetIntegeri_v, GLenum target, GLuint index, GLint* data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetIntegeri_v, target, index, data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BeginTransformFeedback, GLenum primitiveMode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BeginTransformFeedback, primitiveMode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, EndTransformFeedback) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EndTransformFeedback)
@@ -209,7 +209,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BindBufferRange, GLenum target, GLuint index
DECLARE_GL_FUNCTION_STUB_HEAD(void, BindBufferBase, GLenum target, GLuint index, GLuint buffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindBufferBase, target, index, buffer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, TransformFeedbackVaryings, GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TransformFeedbackVaryings, program, count, varyings, bufferMode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetTransformFeedbackVarying, GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetTransformFeedbackVarying, program, index, bufSize, length, size, type, name)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttribIPointer, GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttribIPointer, index, size, type, stride, pointer)
DECLARE_GL_FUNCTION_HEAD(void, VertexAttribIPointer, GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, VertexAttribIPointer, index, size, type, stride, pointer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribIiv, GLuint index, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexAttribIiv, index, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexAttribIuiv, GLuint index, GLenum pname, GLuint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexAttribIuiv, index, pname, params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, VertexAttribI4i, GLuint index, GLint x, GLint y, GLint z, GLint w) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, VertexAttribI4i, index, x, y, z, w)
@@ -0,0 +1,194 @@
#include "../../../Includes.h"
namespace MobileGL {
namespace MG_Impl::GLImpl {
void DisableVertexAttribArray_State(GLuint index) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
auto vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "EnableVertexAttribArray_State",
"No vertex array object is bound."));
return;
}
vao->DisableAttribute(index);
}
void EnableVertexAttribArray_State(GLuint index) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
auto vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "EnableVertexAttribArray_State",
"No vertex array object is bound."));
return;
}
vao->EnableAttribute(index);
}
// TODO: Implement GL_BGRA support
void VertexAttribIPointer_State(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
DataType dataType = MG_Util::ConvertGLEnumToDataType(type);
if (!VertexArrayImpl::ValidateVertexAttribPointerParams(index, size, dataType, stride)) return;
auto vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
"No vertex array object is bound."));
return;
}
auto& vboSlot = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex);
auto vbo = vboSlot.GetBoundObject();
if (!vbo) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
"No buffer is bound to GL_ARRAY_BUFFER."));
return;
}
SizeT offset = reinterpret_cast<SizeT>(pointer);
vao->SetAttributeFormat(index, size, dataType, false, stride, offset, true);
vao->BindAttributeBuffer(index, vbo);
}
// TODO: Implement GL_BGRA support
void VertexAttribPointer_State(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer) {
if (!VertexArrayImpl::ValidateVertexAttributeIndex(index)) return;
DataType dataType = MG_Util::ConvertGLEnumToDataType(type);
if (!VertexArrayImpl::ValidateVertexAttribPointerParams(index, size, dataType, stride)) return;
auto vao = MG_State::pGLContext->GetBoundVertexArray();
if (!vao) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
"No vertex array object is bound."));
return;
}
auto& vboSlot = MG_State::pGLContext->GetBufferBindingSlot(BufferTarget::Vertex);
auto vbo = vboSlot.GetBoundObject();
if (!vbo) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "VertexAttribPointer_State",
"No buffer is bound to GL_ARRAY_BUFFER."));
return;
}
SizeT offset = reinterpret_cast<SizeT>(pointer);
vao->SetAttributeFormat(index, size, dataType, normalized, stride, offset, false);
vao->BindAttributeBuffer(index, vbo);
}
void BindVertexArray_State(GLuint array) {
if (array == 0) {
MG_State::pGLContext->BindVertexArray(0);
return;
}
if (!VertexArrayImpl::ValidateVertexArrayName(array)) return;
if (!MG_State::pGLContext->ValidateVertexArrayObject(array)) {
MG_State::pGLContext->CreateVertexArrayObject(array);
}
MG_State::pGLContext->BindVertexArray(array);
}
void DeleteVertexArrays_State(GLsizei n, const GLuint* arrays) {
if (n < 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "DeleteVertexArrays_State",
"n must be non-negative."));
return;
}
for (GLsizei i = 0; i < n; ++i) {
GLuint vao = arrays[i];
if (vao == 0) continue;
if (!VertexArrayImpl::ValidateVertexArrayName(vao)) continue;
if (MG_State::pGLContext->GetBoundVertexArray() &&
MG_State::pGLContext->GetBoundVertexArray() ==
MG_State::pGLContext->GetVertexArrayObject(vao)) {
MG_State::pGLContext->BindVertexArray(0);
}
MG_State::pGLContext->MarkVertexArrayForDeletion(vao);
}
}
void GenVertexArrays_State(GLsizei n, GLuint* arrays) {
if (n < 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "GenVertexArrays_State",
"n must be non-negative."));
return;
}
auto vaoNames = MG_State::pGLContext->GenVertexArrayNames(n);
Copy(vaoNames.data(), arrays, vaoNames.size());
}
GLboolean IsVertexArray_State(GLuint array) {
if (array == 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "IsVertexArray_State",
"Vertex array name 0 is not supported."));
return GL_FALSE;
}
if (!VertexArrayImpl::ValidateVertexArrayName(array)) return GL_FALSE;
if (!MG_State::pGLContext->ValidateVertexArrayObject(array)) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "IsVertexArray_State",
std::format("Vertex array object {} does not exist.", array)));
return GL_FALSE;
}
return GL_TRUE;
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
GLboolean IsVertexArray(GLuint array) {
return IsVertexArray_State(array);
}
void DisableVertexAttribArray(GLuint index) {
DisableVertexAttribArray_State(index);
}
void EnableVertexAttribArray(GLuint index) {
EnableVertexAttribArray_State(index);
}
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) {
VertexAttribIPointer_State(index, size, type, stride, pointer);
}
void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer) {
VertexAttribPointer_State(index, size, type, normalized, stride, pointer);
}
void BindVertexArray(GLuint array) {
BindVertexArray_State(array);
}
void DeleteVertexArrays(GLsizei n, const GLuint* arrays) {
DeleteVertexArrays_State(n, arrays);
}
void GenVertexArrays(GLsizei n, GLuint* arrays) {
GenVertexArrays_State(n, arrays);
}
}
}
@@ -0,0 +1,15 @@
#pragma once
namespace MobileGL {
namespace MG_Impl::GLImpl {
/* @INSERTION_POINT:FUNCTION_DECLARATION@ */
GLboolean IsVertexArray(GLuint array);
void DisableVertexAttribArray(GLuint index);
void EnableVertexAttribArray(GLuint index);
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
void BindVertexArray(GLuint array);
void DeleteVertexArrays(GLsizei n, const GLuint* arrays);
void GenVertexArrays(GLsizei n, GLuint* arrays);
}
}
@@ -0,0 +1,69 @@
#include "../../../Includes.h"
namespace MobileGL::MG_Impl::GLImpl {
namespace VertexArrayImpl {
bool ValidateVertexArrayName(Uint index) {
if (index == 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayName",
"Vertex array name 0 is not supported."));
return false;
}
bool isValid = MG_State::pGLContext->ValidateVertexArrayName(index);
if (!isValid) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayName",
std::format("Vertex array name {} is not valid.", index)));
}
return true;
}
bool ValidateVertexArrayObject(Uint index) {
if (!MG_State::pGLContext->ValidateVertexArrayObject(index)) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexArrayObject",
std::format("Vertex array object {} does not exist.", index)));
return false;
}
return true;
}
bool ValidateVertexAttributeIndex(Uint index) {
if (index >= MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexAttributeIndex",
std::format("Attribute index {} exceeds maximum of {}.",
index, MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS - 1)));
return false;
}
return true;
}
bool ValidateVertexAttribPointerParams(Uint index, SizeT size, DataType type, Int stride) {
if (size < 1 || size > 4) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Invalid size {} for attribute {}. Must be 1-4.", size, index)));
return false;
}
if (type == DataType::Unknown) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Invalid type {} for attribute {}.", MG_Util::ConvertDataTypeToString(type).c_str(), index)));
return false;
}
if (stride < 0) {
MG_State::pGLContext->RecordError(ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", "ValidateVertexAttribPointerParams",
std::format("Negative stride {} is not allowed for attribute {}.", stride, index)));
return false;
}
return true;
}
}
}
@@ -0,0 +1,10 @@
#pragma once
namespace MobileGL::MG_Impl::GLImpl {
namespace VertexArrayImpl {
bool ValidateVertexArrayName(Uint index);
bool ValidateVertexArrayObject(Uint index);
bool ValidateVertexAttributeIndex(Uint index);
bool ValidateVertexAttribPointerParams(Uint index, SizeT size, DataType type, Int stride);
}
}