From 47f7039720ac39a251b709834ed9f6b2c611fa06 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Fri, 25 Jul 2025 21:33:00 +0800 Subject: [PATCH] [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 --- CMakeLists.txt | 5 + MobileGL/Includes.h | 9 +- MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp | 23 ++ MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.h | 1 + .../MG_Impl/GLImpl/Exporting/Definitions.cpp | 18 +- .../GLImpl/VertexArray/GL_VertexArray.cpp | 194 ++++++++++++++ .../GLImpl/VertexArray/GL_VertexArray.h | 15 ++ .../MG_Impl/GLImpl/VertexArray/Validators.cpp | 69 +++++ .../MG_Impl/GLImpl/VertexArray/Validators.h | 10 + MobileGL/MG_Test/VertexArray/CMakeLists.txt | 4 + .../MG_Test/VertexArray/VertexArrayTest.cpp | 248 ++++++++++++++++++ .../Converters/GLToMG/DataTypeConverter.cpp | 21 ++ .../Converters/GLToMG/DataTypeConverter.h | 7 + .../Converters/MGToGL/DataTypeConverter.cpp | 21 ++ .../Converters/MGToGL/DataTypeConverter.h | 7 + .../Converters/MGToStr/DataTypeConverter.cpp | 22 ++ .../Converters/MGToStr/DataTypeConverter.h | 7 + MobileGL/MG_Util/Types.h | 3 +- 18 files changed, 672 insertions(+), 12 deletions(-) create mode 100644 MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.cpp create mode 100644 MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.h create mode 100644 MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp create mode 100644 MobileGL/MG_Impl/GLImpl/VertexArray/Validators.h create mode 100644 MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.cpp create mode 100644 MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h create mode 100644 MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.cpp create mode 100644 MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h create mode 100644 MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.cpp create mode 100644 MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 95a55066..265adf12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,12 +20,15 @@ add_library(${CMAKE_PROJECT_NAME} SHARED MobileGL/MG_Util/Debug/Log.cpp MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp + MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.cpp MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.cpp MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.cpp MobileGL/MG_Util/Converters/GLToGlslang/GLShaderLangConverter.cpp MobileGL/MG_Util/Converters/MGToGL/ErrorCodeConverter.cpp MobileGL/MG_Util/Converters/MGToGL/BufferEnumConverter.cpp + MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.cpp MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.cpp + MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.cpp MobileGL/MG_Impl/GLXImpl/Exporting/Definitions.cpp MobileGL/MG_Impl/GLXImpl/LookUp/LookUp.cpp @@ -34,6 +37,8 @@ add_library(${CMAKE_PROJECT_NAME} SHARED MobileGL/MG_Impl/EGLImpl/Temporary/TemporaryEGLImpl.cpp # @INSERTION_POINT:SOURCE_FILE_GLIMPL@ # + MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp + MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.cpp MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp diff --git a/MobileGL/Includes.h b/MobileGL/Includes.h index b626fa37..023aca7c 100644 --- a/MobileGL/Includes.h +++ b/MobileGL/Includes.h @@ -113,16 +113,21 @@ inline int __android_log_print(int prio, const char* tag, const char* fmt, ...) #include "MG_State/GLState/VertexArrayState/VertexArrayState.h" /* @INSERTION_POINT:HEADER_FILE_GLIMPL@ */ +#include "MG_Impl/GLImpl/VertexArray/Validators.h" +#include "MG_Impl/GLImpl/VertexArray/GL_VertexArray.h" #include "MG_Impl/GLImpl/Getter/GL_Getter.h" #include "MG_Impl/GLImpl/Buffer/GL_Buffer.h" #include "MG_Impl/GLImpl/Buffer/Validators.h" #include "MG_State/GLState/Core.h" -#include "MG_Util/Converters/GLToMG/BufferEnumConverter.h" #include "MG_Util/Converters/MGToGL/BufferEnumConverter.h" #include "MG_Util/Converters/MGToGL/ErrorCodeConverter.h" -#include "MG_Util/Converters/GLToStr/GLEnumConverter.h" +#include "MG_Util/Converters/MGToGL/DataTypeConverter.h" +#include "MG_Util/Converters/MGToStr/DataTypeConverter.h" #include "MG_Util/Converters/MGToStr/BufferEnumConverter.h" #include "MG_Util/Converters/MGToStr/GLExtensionConverter.h" +#include "MG_Util/Converters/GLToMG/BufferEnumConverter.h" +#include "MG_Util/Converters/GLToMG/DataTypeConverter.h" +#include "MG_Util/Converters/GLToStr/GLEnumConverter.h" #include "MG_Util/Converters/GLToGlslang/GLShaderLangConverter.h" diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp index 66e4aa58..7bedc086 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp @@ -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("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); } diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.h b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.h index e01adaa5..a4017d31 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.h +++ b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.h @@ -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); diff --git a/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp b/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp index 40de21fa..dad43f88 100644 --- a/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp +++ b/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp @@ -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) diff --git a/MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.cpp b/MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.cpp new file mode 100644 index 00000000..48c27934 --- /dev/null +++ b/MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.cpp @@ -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("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("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("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("MG_Impl/GLImpl", "VertexAttribPointer_State", + "No buffer is bound to GL_ARRAY_BUFFER.")); + return; + } + + SizeT offset = reinterpret_cast(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("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("MG_Impl/GLImpl", "VertexAttribPointer_State", + "No buffer is bound to GL_ARRAY_BUFFER.")); + return; + } + + SizeT offset = reinterpret_cast(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("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("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("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("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); + } + } +} diff --git a/MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.h b/MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.h new file mode 100644 index 00000000..b69dea7a --- /dev/null +++ b/MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.h @@ -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); + } +} diff --git a/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp b/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp new file mode 100644 index 00000000..657759a5 --- /dev/null +++ b/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp @@ -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("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("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("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("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("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("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("MG_Impl/GLImpl", "ValidateVertexAttribPointerParams", + std::format("Negative stride {} is not allowed for attribute {}.", stride, index))); + return false; + } + + return true; + } + } +} \ No newline at end of file diff --git a/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.h b/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.h new file mode 100644 index 00000000..70ede4fd --- /dev/null +++ b/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.h @@ -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); + } +} \ No newline at end of file diff --git a/MobileGL/MG_Test/VertexArray/CMakeLists.txt b/MobileGL/MG_Test/VertexArray/CMakeLists.txt index 6665f928..bf27aa89 100644 --- a/MobileGL/MG_Test/VertexArray/CMakeLists.txt +++ b/MobileGL/MG_Test/VertexArray/CMakeLists.txt @@ -13,13 +13,17 @@ add_executable( ${MGL_ROOT}/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp ${MGL_ROOT}/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp ${MGL_ROOT}/MobileGL/MG_Impl/GLImpl/Buffer/Validators.cpp + ${MGL_ROOT}/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp + ${MGL_ROOT}/MobileGL/MG_Impl/GLImpl/VertexArray/GL_VertexArray.cpp ${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp ${MGL_ROOT}/MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.cpp ${MGL_ROOT}/MobileGL/MG_Util/Converters/MGToStr/BufferEnumConverter.cpp ${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToGlslang/GLShaderLangConverter.cpp ${MGL_ROOT}/MobileGL/MG_Util/Converters/MGToGL/ErrorCodeConverter.cpp ${MGL_ROOT}/MobileGL/MG_Util/Converters/MGToGL/BufferEnumConverter.cpp + ${MGL_ROOT}/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.cpp ${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToMG/BufferEnumConverter.cpp + ${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.cpp ${MGL_ROOT}/MobileGL/MG_Backend/Init.cpp ${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp ) diff --git a/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp b/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp index 45caef9a..dcd8f5b4 100644 --- a/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp +++ b/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp @@ -197,3 +197,251 @@ TEST_F(VertexArrayTest, BoundVAOPreservesState) { ASSERT_FALSE(vao2->IsAttributeEnabled(0)); } + + +using namespace MobileGL::MG_Impl::GLImpl; + +class GeneralVertexArrayTest : public ::testing::Test { +protected: + void SetUp() override { + MG_State::pGLContext = new MG_State::GLState::GLContext(); + } + + void TearDown() override { + delete MG_State::pGLContext; + MG_State::pGLContext = nullptr; + } + + GLuint CreateVAO() { + GLuint vao; + GenVertexArrays(1, &vao); + BindVertexArray(vao); + return vao; + } + + GLuint CreateVBO(GLenum target, GLsizeiptr size, const void* data = nullptr) { + GLuint vbo; + GenBuffers(1, &vbo); + BindBuffer(target, vbo); + BufferData(target, size, data, GL_STATIC_DRAW); + return vbo; + } +}; + +TEST_F(GeneralVertexArrayTest, General_VAOLifecycle) { + GLuint vaos[3]; + + GenVertexArrays(3, vaos); + EXPECT_NE(vaos[0], 0); + EXPECT_NE(vaos[1], 0); + EXPECT_NE(vaos[2], 0); + EXPECT_NE(vaos[0], vaos[1]); + + BindVertexArray(vaos[0]); + EXPECT_EQ(IsVertexArray(vaos[0]), GL_TRUE); + + GLuint deleteVao = vaos[1]; + DeleteVertexArrays(1, &deleteVao); + + BindVertexArray(deleteVao); + EXPECT_EQ(GetError(), GL_INVALID_OPERATION); + + DeleteVertexArrays(1, &vaos[0]); + DeleteVertexArrays(1, &vaos[2]); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_VertexAttributeConfiguration) { + GLuint vao = CreateVAO(); + GLuint vbo = CreateVBO(GL_ARRAY_BUFFER, 128); + + VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); + EnableVertexAttribArray(0); + + VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); + EnableVertexAttribArray(1); + + auto vaoObj = MG_State::pGLContext->GetVertexArrayObject(vao); + ASSERT_NE(vaoObj, nullptr); + + const auto& attr0 = vaoObj->GetAttribute(0); + EXPECT_TRUE(attr0.Enabled); + EXPECT_EQ(attr0.Size, 3); + EXPECT_EQ(attr0.Type, DataType::Float32); + EXPECT_EQ(attr0.Offset, 0); + + const auto& attr1 = vaoObj->GetAttribute(1); + EXPECT_TRUE(attr1.Enabled); + EXPECT_EQ(attr1.Offset, 3 * sizeof(float)); + + DisableVertexAttribArray(1); + EXPECT_FALSE(vaoObj->GetAttribute(1).Enabled); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_ElementBufferBinding) { + GLuint vao = CreateVAO(); + GLuint ebo = CreateVBO(GL_ELEMENT_ARRAY_BUFFER, 256); + + auto vaoObj = MG_State::pGLContext->GetVertexArrayObject(vao); + ASSERT_NE(vaoObj, nullptr); + ASSERT_NE(vaoObj->GetElementBuffer(), nullptr); + + GLuint newEbo; + GenBuffers(1, &newEbo); + BindBuffer(GL_ELEMENT_ARRAY_BUFFER, newEbo); + + EXPECT_EQ(vaoObj->GetElementBuffer(), MG_State::pGLContext->GetBufferObject(newEbo)); + + GLuint vao2 = CreateVAO(); + GLuint ebo2 = CreateVBO(GL_ELEMENT_ARRAY_BUFFER, 128); + + auto vaoObj2 = MG_State::pGLContext->GetVertexArrayObject(vao2); + EXPECT_NE(vaoObj->GetElementBuffer(), vaoObj2->GetElementBuffer()); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_IntegerAttributes) { + GLuint vao = CreateVAO(); + GLuint vbo = CreateVBO(GL_ARRAY_BUFFER, 128); + + VertexAttribIPointer(2, 4, GL_UNSIGNED_INT, sizeof(GLuint) * 8, (void*)(sizeof(GLuint) * 4)); + EnableVertexAttribArray(2); + + auto vaoObj = MG_State::pGLContext->GetVertexArrayObject(vao); + const auto& attr = vaoObj->GetAttribute(2); + EXPECT_TRUE(attr.Enabled); + EXPECT_EQ(attr.Size, 4); + EXPECT_EQ(attr.Type, DataType::Uint32); + EXPECT_EQ(attr.Offset, sizeof(GLuint) * 4); + EXPECT_TRUE(attr.IsInteger); + EXPECT_FALSE(attr.Normalized); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_StatePreservation) { + GLuint vao1 = CreateVAO(); + GLuint vbo1 = CreateVBO(GL_ARRAY_BUFFER, 64); + + VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr); + EnableVertexAttribArray(0); + + GLuint vao2; + GenVertexArrays(1, &vao2); + BindVertexArray(vao2); + GLuint vbo2 = CreateVBO(GL_ARRAY_BUFFER, 128); + VertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 0, nullptr); + EnableVertexAttribArray(1); + + BindVertexArray(vao1); + + auto vaoObj1 = MG_State::pGLContext->GetVertexArrayObject(vao1); + EXPECT_TRUE(vaoObj1->IsAttributeEnabled(0)); + EXPECT_FALSE(vaoObj1->IsAttributeEnabled(1)); + + auto vaoObj2 = MG_State::pGLContext->GetVertexArrayObject(vao2); + EXPECT_TRUE(vaoObj2->IsAttributeEnabled(1)); + EXPECT_FALSE(vaoObj2->IsAttributeEnabled(0)); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_ErrorConditions) { + VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + EXPECT_EQ(GetError(), GL_INVALID_OPERATION); + + GLuint vao = CreateVAO(); + EnableVertexAttribArray(MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS); + EXPECT_EQ(GetError(), GL_INVALID_VALUE); + + VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + EXPECT_EQ(GetError(), GL_INVALID_OPERATION); + + GLuint vbo = CreateVBO(GL_ARRAY_BUFFER, 64); + VertexAttribPointer(0, 3, 0xFFFFFFFF, GL_FALSE, 0, nullptr); + EXPECT_EQ(GetError(), GL_INVALID_ENUM); + + VertexAttribPointer(0, 5, GL_FLOAT, GL_FALSE, 0, nullptr); + EXPECT_EQ(GetError(), GL_INVALID_VALUE); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_ComplexUsage) { + GLuint vao1 = CreateVAO(); + GLuint vboPos = CreateVBO(GL_ARRAY_BUFFER, 256); + GLuint vboColor = CreateVBO(GL_ARRAY_BUFFER, 128); + GLuint ebo1 = CreateVBO(GL_ELEMENT_ARRAY_BUFFER, 64); + + VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + EnableVertexAttribArray(0); + + BindBuffer(GL_ARRAY_BUFFER, vboColor); + VertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr); + EnableVertexAttribArray(1); + + GLuint vao2; + GenVertexArrays(1, &vao2); + BindVertexArray(vao2); + GLuint vboNormal = CreateVBO(GL_ARRAY_BUFFER, 192); + GLuint ebo2 = CreateVBO(GL_ELEMENT_ARRAY_BUFFER, 96); + + VertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + EnableVertexAttribArray(2); + + BindVertexArray(vao1); + + auto vaoObj1 = MG_State::pGLContext->GetVertexArrayObject(vao1); + EXPECT_TRUE(vaoObj1->IsAttributeEnabled(0)); + EXPECT_TRUE(vaoObj1->IsAttributeEnabled(1)); + EXPECT_FALSE(vaoObj1->IsAttributeEnabled(2)); + EXPECT_NE(vaoObj1->GetElementBuffer(), nullptr); + + auto vaoObj2 = MG_State::pGLContext->GetVertexArrayObject(vao2); + EXPECT_TRUE(vaoObj2->IsAttributeEnabled(2)); + EXPECT_FALSE(vaoObj2->IsAttributeEnabled(0)); + EXPECT_NE(vaoObj2->GetElementBuffer(), nullptr); + + DeleteVertexArrays(1, &vao1); + DeleteVertexArrays(1, &vao2); + GLuint buffers[] = { vboPos, vboColor, ebo1, vboNormal, ebo2 }; + DeleteBuffers(5, buffers); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_BindWithoutCreation) { + GLuint vao = 1; + + BindVertexArray(vao); + EXPECT_EQ(GetError(), GL_NO_ERROR); + + EXPECT_NE(MG_State::pGLContext->GetVertexArrayObject(vao), nullptr); + + GLuint vbo = CreateVBO(GL_ARRAY_BUFFER, 64); + VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + EXPECT_EQ(GetError(), GL_NO_ERROR); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} + +TEST_F(GeneralVertexArrayTest, General_DeleteBoundVAO) { + GLuint vao = CreateVAO(); + GLuint vbo = CreateVBO(GL_ARRAY_BUFFER, 64); + VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + EnableVertexAttribArray(0); + + DeleteVertexArrays(1, &vao); + + EXPECT_EQ(MG_State::pGLContext->GetBoundVertexArray(), nullptr); + EXPECT_EQ(MG_State::pGLContext->GetVertexArrayObject(vao), nullptr); + + VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + EXPECT_EQ(GetError(), GL_INVALID_OPERATION); + + EXPECT_EQ(GetError(), GL_NO_ERROR); +} \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.cpp new file mode 100644 index 00000000..5f314e0d --- /dev/null +++ b/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.cpp @@ -0,0 +1,21 @@ +#include "../../../Includes.h" + +namespace MobileGL { + namespace MG_Util { + DataType ConvertGLEnumToDataType(GLenum type) { + switch (type) { + case GL_BYTE: return DataType::Int8; + case GL_UNSIGNED_BYTE: return DataType::Uint8; + case GL_SHORT: return DataType::Int16; + case GL_UNSIGNED_SHORT: return DataType::Uint16; + case GL_INT: return DataType::Int32; + case GL_UNSIGNED_INT: return DataType::Uint32; + case GL_HALF_FLOAT: return DataType::Float16; + case GL_FLOAT: return DataType::Float32; + case GL_DOUBLE: return DataType::Float64; + default: + return DataType::Unknown; + } + } + } +} \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h b/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h new file mode 100644 index 00000000..b5528d72 --- /dev/null +++ b/MobileGL/MG_Util/Converters/GLToMG/DataTypeConverter.h @@ -0,0 +1,7 @@ +#pragma once + +namespace MobileGL { + namespace MG_Util { + DataType ConvertGLEnumToDataType(GLenum type); + } +} \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.cpp b/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.cpp new file mode 100644 index 00000000..62b11020 --- /dev/null +++ b/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.cpp @@ -0,0 +1,21 @@ +#include "../../../Includes.h" + +namespace MobileGL { + namespace MG_Util { + GLenum ConvertDataTypeToGLEnum(DataType type) { + switch (type) { + case DataType::Int8: return GL_BYTE; + case DataType::Uint8: return GL_UNSIGNED_BYTE; + case DataType::Int16: return GL_SHORT; + case DataType::Uint16: return GL_UNSIGNED_SHORT; + case DataType::Int32: return GL_INT; + case DataType::Uint32: return GL_UNSIGNED_INT; + case DataType::Float16: return GL_HALF_FLOAT; + case DataType::Float32: return GL_FLOAT; + case DataType::Float64: return GL_DOUBLE; + default: + return GL_UNKNOWN_MGL; + } + } + } +} \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h b/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h new file mode 100644 index 00000000..1fd93600 --- /dev/null +++ b/MobileGL/MG_Util/Converters/MGToGL/DataTypeConverter.h @@ -0,0 +1,7 @@ +#pragma once + +namespace MobileGL { + namespace MG_Util { + GLenum ConvertDataTypeToGLEnum(DataType type); + } +} \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.cpp b/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.cpp new file mode 100644 index 00000000..120908b9 --- /dev/null +++ b/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.cpp @@ -0,0 +1,22 @@ +#include "../../../Includes.h" + +namespace MobileGL { + namespace MG_Util { + String ConvertDataTypeToString(DataType type) { + switch (type) { + case DataType::Int8: return "Int8"; + case DataType::Uint8: return "Uint8"; + case DataType::Int16: return "Int16"; + case DataType::Uint16: return "Uint16"; + case DataType::Int32: return "Int32"; + case DataType::Uint32: return "Uint32"; + case DataType::Float16: return "Float16"; + case DataType::Float32: return "Float32"; + case DataType::Float64: return "Float64"; + case DataType::Fixed32: return "Fixed32"; + case DataType::Unknown: + default: return "Unknown"; + } + } + } +} \ No newline at end of file diff --git a/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h b/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h new file mode 100644 index 00000000..c720dab3 --- /dev/null +++ b/MobileGL/MG_Util/Converters/MGToStr/DataTypeConverter.h @@ -0,0 +1,7 @@ +#pragma once + +namespace MobileGL { + namespace MG_Util { + String ConvertDataTypeToString(DataType type); + } +} \ No newline at end of file diff --git a/MobileGL/MG_Util/Types.h b/MobileGL/MG_Util/Types.h index 05c41e31..096a5960 100644 --- a/MobileGL/MG_Util/Types.h +++ b/MobileGL/MG_Util/Types.h @@ -74,7 +74,8 @@ namespace MobileGL { Float16, Float32, Float64, - Fixed32 + Fixed32, + Unknown = -1 }; // represents a range of [start, end)