[Feat] (...): Add BufferState and VertexBufferState while implementing these gl functions.

This commit is contained in:
BZLZHH
2025-05-01 22:20:34 +08:00
parent 369b9b320b
commit 33104f699a
16 changed files with 702 additions and 23 deletions
+5 -1
View File
@@ -59,8 +59,12 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
MG/MG_GL/State/Core/GLState.cpp
MG/MG_GL/State/Common/CommonState.cpp
MG/MG_GL/State/Texture/TextureState.cpp
MG/MG_GL/State/VertexArray/VertexArrayState.cpp
MG/MG_GL/State/Buffer/BufferState.cpp
# MG_GL/BackendLoader
MG/MG_GL/BackendLoader/GLES/Loader.cpp
+16
View File
@@ -22,6 +22,22 @@ namespace MG_Constants {
inline const int LOG_LEVEL_INFO = 0x0013;
inline const int LOG_LEVEL_FATAL = 0x0014;
}
namespace Buffer {
static const std::unordered_set<GLenum> VALID_PARAM_NAMES = {
GL_BUFFER_ACCESS, GL_BUFFER_MAPPED, GL_BUFFER_SIZE, GL_BUFFER_USAGE
}; // OpenGL 3
static const std::unordered_set<GLenum> VALID_TARGETS = {
GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TEXTURE_BUFFER,
GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER
}; // OpenGL 3
static const std::unordered_set<GLenum> VALID_ACCESS = {
GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE
}; // OpenGL 3
}
namespace PixelStore {
static const std::unordered_map<GLenum, GLint> DEFAULT_VALUES_MAP = {
+6
View File
@@ -44,6 +44,12 @@
#ifndef MOBILEGL_TEXTURESTATE_H
#include "MG_GL/State/Texture/TextureState.h"
#endif
#ifndef MOBILEGL_VERTEXARRAYSTATE_H
#include "MG_GL/State/VertexArray/VertexArrayState.h"
#endif
#ifndef MOBILEGL_BUFFERSTATE_H
#include "MG_GL/State/Buffer/BufferState.h"
#endif
#ifndef MOBILEGL_LOOKUP_H
#include "MG_GL/Implementations/GLX/LookUp/LookUp.h"
#endif
@@ -5,5 +5,104 @@
#include "GL_Buffer.h"
namespace MG_GL::GL {
void* MapBuffer(GLenum target, GLenum access) {
MG_Util::Debug::LogD("glMapBuffer(target=0x%x, access=0x%x)", target, access);
void* mappedPtr = nullptr;
GLenum err = MG_State::AcquireBufferMemory(target, access, &mappedPtr);
if (err != GL_NO_ERROR) {
MG_State::SetError(err);
MG_Util::Debug::LogE("glMapBuffer failed: %s",
MG_Util::Debug::GLEnumToString(err));
return nullptr;
}
MG_Util::Debug::LogD("glMapBuffer returns %p", mappedPtr);
return mappedPtr;
}
GLboolean UnmapBuffer(GLenum target) {
MG_Util::Debug::LogD("glUnmapBuffer(target=0x%x)", target);
GLenum err = MG_State::ReleaseBufferMemory(target);
if (err != GL_NO_ERROR) {
MG_State::SetError(err);
MG_Util::Debug::LogE("glUnmapBuffer failed: %s",
MG_Util::Debug::GLEnumToString(err));
return GL_FALSE;
}
MG_Util::Debug::LogD("glUnmapBuffer succeeded");
return GL_TRUE;
}
void BindBuffer(GLenum target, GLuint buffer) {
MG_Util::Debug::LogD("glBindBuffer, target: %d, buffer: %d", target, buffer);
if (buffer != 0 && !MG_State::ValidateBufferHandle(buffer)) {
MG_State::SetError(GL_INVALID_VALUE);
MG_Util::Debug::LogE("Invalid buffer handle: %u", buffer);
return;
}
GLenum result = MG_State::BindBuffer(target, buffer);
if (result == GL_NO_ERROR)
return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
MG_Util::Debug::LogD("glBufferData, target: %d, size: %zd, data: %p, usage: %d",
target, size, data, usage);
GLenum result = MG_State::CommitBufferStorage(target, size, data, usage);
if (result == GL_NO_ERROR)
return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
MG_Util::Debug::LogD("glGetBufferParameteriv, target: %d, pname: %d, params: %p",
target, pname, params);
GLenum result = MG_State::QueryBufferPropertyIntVector(target, pname, params);
if (result == GL_NO_ERROR)
return;
MG_State::SetError(result);
MG_Util::Debug::LogE("GetBufferParameteriv not implemented");
}
void GenBuffers(GLsizei n, GLuint* buffers) {
MG_Util::Debug::LogD("glGenBuffers, n: %d, buffers: %p", n, buffers);
if (n < 0) {
MG_State::SetError(GL_INVALID_VALUE);
MG_Util::Debug::LogE("Invalid buffer count: %d", n);
return;
}
GLenum result = MG_State::CreateBuffers(n, buffers);
if (result == GL_NO_ERROR) {
MG_Util::Debug::LogD("Generated buffers:");
for (GLsizei i = 0; i < n; ++i) {
MG_Util::Debug::LogD(" Buffer[%d] = %u", i, buffers[i]);
}
return;
}
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
GLboolean IsBuffer(GLuint buffer) {
MG_Util::Debug::LogD("glIsBuffer, buffer: %u", buffer);
if (buffer == 0) {
return GL_FALSE;
}
bool isValid = MG_State::ValidateBufferHandle(buffer);
// Should we report gl error here or in MG_State?
MG_Util::Debug::LogD("Buffer %u is %s", buffer, isValid ? "valid" : "invalid");
return isValid ? GL_TRUE : GL_FALSE;
}
}
@@ -8,7 +8,13 @@
#include "../../../../Includes.h"
namespace MG_GL::GL {
void* MapBuffer(GLenum target, GLenum access);
GLboolean UnmapBuffer(GLenum target);
void BindBuffer(GLenum target, GLuint buffer);
void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
void GenBuffers(GLsizei n, GLuint* buffers);
GLboolean IsBuffer(GLuint buffer);
}
#endif //MOBILEGL_GL_BUFFER_H
@@ -9,7 +9,7 @@ MG_EXPORT type gl##name(__VA_ARGS__) {
#define DECLARE_GL_FUNCTION_STUB_END(type,name,...) \
MG_Util::Debug::LogW("Stub function: %s(...)", __FUNCTION__); \
return (type)0; \
return (type)1; \
}
#define DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(type,name,...) \
@@ -31,12 +31,12 @@ MG_EXPORT type gl##name(__VA_ARGS__) {
DECLARE_GL_FUNCTION_HEAD(const GLubyte*, GetStringi, GLenum name, GLuint index) DECLARE_GL_FUNCTION_END(const GLubyte*, GetStringi, name, index)
DECLARE_GL_FUNCTION_HEAD(const GLubyte*, GetString, GLenum name) DECLARE_GL_FUNCTION_END(const GLubyte*, GetString, name)
DECLARE_GL_FUNCTION_STUB_HEAD(void*, MapBuffer, GLenum target, GLenum access) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void*, MapBuffer, target, access)
DECLARE_GL_FUNCTION_HEAD(void*, MapBuffer, GLenum target, GLenum access) DECLARE_GL_FUNCTION_END(void*, MapBuffer, target, access)
DECLARE_GL_FUNCTION_HEAD(void, ClearDepth, GLclampd depth) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearDepth, depth)
DECLARE_GL_FUNCTION_HEAD(void, ActiveTexture, GLenum texture) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ActiveTexture, texture)
DECLARE_GL_FUNCTION_STUB_HEAD(void, AttachShader, GLuint program, GLuint shader) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, AttachShader, program,shader)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindAttribLocation, program,index,name)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BindBuffer, GLenum target, GLuint buffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindBuffer, target,buffer)
DECLARE_GL_FUNCTION_HEAD(void, BindBuffer, GLenum target, GLuint buffer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindBuffer, target,buffer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BindFramebuffer, GLenum target, GLuint framebuffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindFramebuffer, target,framebuffer)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BindRenderbuffer, GLenum target, GLuint renderbuffer) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BindRenderbuffer, target,renderbuffer)
DECLARE_GL_FUNCTION_HEAD(void, BindTexture, GLenum target, GLuint texture) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindTexture, target,texture)
@@ -45,7 +45,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquation, GLenum mode) DECLARE_GL_FUNCT
DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendEquationSeparate, modeRGB,modeAlpha)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendFunc, GLenum sfactor, GLenum dfactor) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendFunc, sfactor,dfactor)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendFuncSeparate, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BlendFuncSeparate, sfactorRGB,dfactorRGB,sfactorAlpha,dfactorAlpha)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BufferData, target,size,data,usage)
DECLARE_GL_FUNCTION_HEAD(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BufferData, target,size,data,usage)
DECLARE_GL_FUNCTION_STUB_HEAD(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BufferSubData, target,offset,size,data)
DECLARE_GL_FUNCTION_HEAD(GLenum, CheckFramebufferStatus, GLenum target) DECLARE_GL_FUNCTION_END(GLenum, CheckFramebufferStatus, target)
DECLARE_GL_FUNCTION_HEAD(void, Clear, GLbitfield mask) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, Clear, mask)
@@ -76,13 +76,13 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, DisableVertexAttribArray, GLuint index) DECL
DECLARE_GL_FUNCTION_HEAD(void, DrawArrays, GLenum mode, GLint first, GLsizei count) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawArrays, mode,first,count)
DECLARE_GL_FUNCTION_HEAD(void, DrawElements, GLenum mode, GLsizei count, GLenum type, const void *indices) DECLARE_GL_FUNCTION_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)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FramebufferTexture2D, target,attachment,textarget,texture,level)
DECLARE_GL_FUNCTION_STUB_HEAD(void, FrontFace, GLenum mode) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, FrontFace, mode)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GenBuffers, GLsizei n, GLuint *buffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GenBuffers, n,buffers)
DECLARE_GL_FUNCTION_HEAD(void, GenBuffers, GLsizei n, GLuint *buffers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GenBuffers, n,buffers)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GenerateMipmap, GLenum target) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GenerateMipmap, target)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GenFramebuffers, GLsizei n, GLuint *framebuffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GenFramebuffers, n,framebuffers)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GenRenderbuffers, GLsizei n, GLuint *renderbuffers) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GenRenderbuffers, n,renderbuffers)
@@ -92,7 +92,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetActiveUniform, GLuint program, GLuint ind
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetAttachedShaders, GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetAttachedShaders, program,maxCount,count,shaders)
DECLARE_GL_FUNCTION_STUB_HEAD(GLint, GetAttribLocation, GLuint program, const GLchar *name) DECLARE_GL_FUNCTION_STUB_END(GLint, GetAttribLocation, program,name)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetBooleanv, GLenum pname, GLboolean *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetBooleanv, pname,data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetBufferParameteriv, GLenum target, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetBufferParameteriv, target,pname,params)
DECLARE_GL_FUNCTION_HEAD(void, GetBufferParameteriv, GLenum target, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetBufferParameteriv, target,pname,params)
DECLARE_GL_FUNCTION_HEAD(GLenum, GetError) DECLARE_GL_FUNCTION_END(GLenum, GetError)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetFloatv, GLenum pname, GLfloat *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetFloatv, pname,data)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetFramebufferAttachmentParameteriv, target,attachment,pname,params)
@@ -113,7 +113,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)
@@ -172,7 +172,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)
@@ -188,7 +188,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BeginQuery, GLenum target, GLuint id) DECLAR
DECLARE_GL_FUNCTION_STUB_HEAD(void, EndQuery, GLenum target) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EndQuery, target)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryiv, GLenum target, GLenum pname, GLint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetQueryiv, target,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetQueryObjectuiv, id,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, UnmapBuffer, GLenum target) DECLARE_GL_FUNCTION_STUB_END(GLboolean, UnmapBuffer, target)
DECLARE_GL_FUNCTION_HEAD(GLboolean, UnmapBuffer, GLenum target) DECLARE_GL_FUNCTION_END(GLboolean, UnmapBuffer, target)
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetBufferPointerv, GLenum target, GLenum pname, void **params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetBufferPointerv, target,pname,params)
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawBuffers, GLsizei n, const GLenum *bufs) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawBuffers, n,bufs)
DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix2x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix2x3fv, location,count,transpose,value)
@@ -201,9 +201,9 @@ 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_STUB_HEAD(void, FlushMappedBufferRange, GLenum target, GLintptr offset, GLsizeiptr length) DECLARE_GL_FUNCTION_STUB_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_HEAD(void, BindVertexArray, GLuint array) DECLARE_GL_FUNCTION_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_HEAD(void, GenVertexArrays, GLsizei n, GLuint *arrays) DECLARE_GL_FUNCTION_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_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)
@@ -212,7 +212,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)
@@ -5,5 +5,49 @@
#include "GL_VertexArray.h"
namespace MG_GL::GL {
void GenVertexArrays(GLsizei n, GLuint* arrays) {
MG_Util::Debug::LogD("glGenVertexArrays, n: %d, arrays: %p", n, arrays);
GLenum result = MG_State::CreateVertexArrays(n, arrays);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
void BindVertexArray(GLuint array) {
MG_Util::Debug::LogD("glBindVertexArray, array: %u", array);
GLenum result = MG_State::BindVertexArray(array);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
void EnableVertexAttribArray(GLuint index) {
MG_Util::Debug::LogD("glEnableVertexAttribArray, index: %u", index);
GLenum result = MG_State::EnableVertexAttribArray(index);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
void VertexAttribPointer(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, const void* pointer) {
MG_Util::Debug::LogD("glVertexAttribPointer, index: %u, size: %d, type: %s, norm: %d, stride: %d, ptr: %p",
index, size, MG_Util::Debug::GLEnumToString(type), normalized, stride, pointer);
GLenum result = MG_State::SetVertexAttributeLayout(index, size, type, normalized, stride, pointer);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
void VertexAttribIPointer(GLuint index, GLint size, GLenum type,
GLsizei stride, const void* pointer) {
MG_Util::Debug::LogD("glVertexAttribIPointer, index: %u, size: %d, type: %s, stride: %d, ptr: %p",
index, size, MG_Util::Debug::GLEnumToString(type), stride, pointer);
GLenum result = MG_State::SetVertexAttributeLayoutInt(index, size, type, stride, pointer);
if (result == GL_NO_ERROR) return;
MG_State::SetError(result);
MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result));
}
}
@@ -8,7 +8,11 @@
#include "../../../../Includes.h"
namespace MG_GL::GL {
void GenVertexArrays(GLsizei n, GLuint* arrays);
void BindVertexArray(GLuint array);
void EnableVertexAttribArray(GLuint index);
void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
}
#endif //MOBILEGL_GL_VERTEXARRAY_H
+196
View File
@@ -0,0 +1,196 @@
//
// Created by BZLZHH on 2025/5/1.
//
// TODO: Add more gl error check for buffer state manager.
#include "BufferState.h"
GLenum BufferState::Create(GLuint* buffer) {
MG_Util::Debug::LogD("MG_State: Buffer: Create called");
if (!buffer) return GL_INVALID_VALUE;
GLuint id = 0;
if (!freeIds_.empty()) {
id = *freeIds_.begin();
freeIds_.erase(freeIds_.begin());
} else {
id = ++lastId_;
}
*buffer = id;
BufferObject& obj = buffers_[id];
MG_Util::Debug::LogD("MG_State: Buffer: Create created buffer %d", id);
obj.generated = true;
return GL_NO_ERROR;
}
GLenum BufferState::CreateN(GLsizei n, GLuint* buffers) {
MG_Util::Debug::LogD("MG_State: Buffer: CreateN called with n=%d", n);
if (n < 0) return GL_INVALID_VALUE;
for (GLsizei i = 0; i < n; ++i) {
GLenum result = Create(&buffers[i]);
if (result != GL_NO_ERROR) {
MG_Util::Debug::LogE("MG_State: Buffer: CreateN create buffer failed with error 0x%x", result);
return result;
}
}
MG_Util::Debug::LogD("MG_State: Buffer: CreateN created buffers successfully");
return GL_NO_ERROR;
}
GLenum BufferState::Bind(GLenum target, GLuint buffer) {
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
MG_Util::Debug::LogD("MG_State: Buffer: Bind called with target=0x%x, buffer=%u", target, buffer);
if (buffer != 0) {
auto it = buffers_.find(buffer);
if (it == buffers_.end()) {
buffers_[buffer];
} else {
BufferObject& obj = it->second;
if (obj.target != 0 && obj.target != target) {
MG_Util::Debug::LogE("MG_State: Buffer: Bind can not bind a buffer to different target 0x%x, current bind target is 0x%x", target, obj.target);
return GL_INVALID_OPERATION;
}
}
buffers_[buffer].target = target;
}
currentBindings_[target] = buffer;
MG_Util::Debug::LogD("MG_State: Buffer: Bind succeed bind buffer %u to target 0x%x", buffer, target);
return GL_NO_ERROR;
}
GLenum BufferState::CommitStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage called on target 0x%x",target);
auto it = currentBindings_.find(target);
if (it == currentBindings_.end() || it->second == 0)
return GL_INVALID_OPERATION;
BufferObject& obj = buffers_[it->second];
MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage get buffer object %u at target 0x%x",it->second,target);
obj.usage = usage;
obj.data.resize(size);
if (data) memcpy(obj.data.data(), data, size);
MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage buffer at target 0x%x committed storage, size = %zu, usage=0x%x", target, size, usage);
return GL_NO_ERROR;
}
GLenum BufferState::AcquireBufferMemory(GLenum target, GLenum access, void** mappedPointer) {
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
if (MG_Constants::Buffer::VALID_ACCESS.find(access) == MG_Constants::Buffer::VALID_ACCESS.end()) {
return GL_INVALID_ENUM;
MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemory buffer at target 0x%x acquired mapped memory, access mode = 0x%x", target, access);
}
auto it = currentBindings_.find(target);
if (it == currentBindings_.end() || it->second == 0)
return GL_INVALID_OPERATION;
BufferObject& obj = buffers_[it->second];
if (obj.isMapped) return GL_INVALID_OPERATION;
obj.isMapped = true;
*mappedPointer = obj.data.data();
obj.isMapped = true;
obj.accessMode = access;
return GL_NO_ERROR;
}
GLenum BufferState::ReleaseBufferMemory(GLenum target) {
MG_Util::Debug::LogD("MG_State: Buffer: ReleaseBufferMemory called on target 0x%x",target);
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
auto it = currentBindings_.find(target);
if (it == currentBindings_.end() || it->second == 0)
return GL_INVALID_OPERATION;
BufferObject& obj = buffers_[it->second];
if (!obj.isMapped) return GL_INVALID_OPERATION;
obj.isMapped = false;
obj.accessMode = GL_READ_WRITE;
MG_Util::Debug::LogD("MG_State: Buffer: ReleaseBufferMemory buffer at target 0x%x released mapped memory", target);
return GL_NO_ERROR;
}
bool BufferState::ValidateHandle(GLuint buffer) {
bool isvalid = buffers_.count(buffer) > 0;
MG_Util::Debug::LogD("MG_State: Buffer: ValidateHandle called on buffer %u returns %d", buffer, isvalid);
return isvalid;
}
void BufferState::Delete(GLuint buffer) {
if (buffers_.erase(buffer)) {
freeIds_.insert(buffer);
for (auto& [target, id] : currentBindings_) {
if (id == buffer) id = 0;
}
}
MG_Util::Debug::LogD("MG_State: Buffer: Delete buffer %u", buffer);
}
bool BufferState::IsValidTarget_(GLenum target) {
MG_Util::Debug::LogD("MG_State: Buffer: IsValidTarget_ called with target=0x%x,result=%d", target, !(MG_Constants::Buffer::VALID_TARGETS.find(target) == MG_Constants::Buffer::VALID_TARGETS.end()));
return !(MG_Constants::Buffer::VALID_TARGETS.find(target) == MG_Constants::Buffer::VALID_TARGETS.end());
}
GLenum BufferState::QueryPropertyIntVector(GLenum target, GLenum pname, GLint* params) const {
MG_Util::Debug::LogD("MG_State: Buffer: QueryPropertyIntVector called at target 0x%x,param name = 0x%x",target,pname);
static const std::set<GLenum> validTargets = {
GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER
};
if (validTargets.find(target) == validTargets.end()) {
return GL_INVALID_ENUM;
}
if (MG_Constants::Buffer::VALID_PARAM_NAMES.find(pname) == MG_Constants::Buffer::VALID_PARAM_NAMES.end()) {
return GL_INVALID_ENUM;
}
auto bindingIt = currentBindings_.find(target);
if (bindingIt == currentBindings_.end() || bindingIt->second == 0) {
return GL_INVALID_OPERATION;
}
GLuint bufferId = bindingIt->second;
auto bufferIt = buffers_.find(bufferId);
if (bufferIt == buffers_.end()) {
return GL_INVALID_OPERATION;
}
const BufferObject& buffer = bufferIt->second;
switch (pname) {
case GL_BUFFER_ACCESS:
*params = static_cast<GLint>(buffer.accessMode);
break;
case GL_BUFFER_MAPPED:
*params = buffer.isMapped ? GL_TRUE : GL_FALSE;
break;
case GL_BUFFER_SIZE:
*params = static_cast<GLint>(buffer.data.size());
break;
case GL_BUFFER_USAGE:
*params = static_cast<GLint>(buffer.usage);
break;
MG_Util::Debug::LogD("MG_State: Buffer: QueryPropertyIntVector Query info about buffer %u succeed",buffer.target);
default:
return GL_INVALID_ENUM;
}
return GL_NO_ERROR;
}
GLuint BufferState::GetCurrentBinding(GLenum target) const {
auto it = currentBindings_.find(target);
if (it != currentBindings_.end()) {
return it->second;
}
return 0;
}
+44
View File
@@ -0,0 +1,44 @@
//
// Created by BZLZHH on 2025/5/1.
//
#ifndef MOBILEGL_BUFFERSTATE_H
#define MOBILEGL_BUFFERSTATE_H
#define MOBILEGL_GLSTATE_H
#include "../../../Includes.h"
class BufferState {
public:
struct BufferObject {
GLenum target = 0;
GLenum usage = GL_STATIC_DRAW;
std::vector<GLubyte> data;
bool isMapped = false;
bool generated = false;
GLenum accessMode = GL_READ_WRITE;
};
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum Create(GLuint* buffer);
GLenum CreateN(GLsizei n, GLuint* buffers);
GLenum Bind(GLenum target, GLuint buffer);
GLenum CommitStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPointer);
GLenum ReleaseBufferMemory(GLenum target);
GLenum QueryPropertyIntVector(GLenum target, GLenum pname, GLint* params) const;
bool ValidateHandle(GLuint buffer);
void Delete(GLuint buffer);
GLuint GetCurrentBinding(GLenum target) const;
private:
std::unordered_map<GLuint, BufferObject> buffers_;
std::set<GLuint> freeIds_;
GLuint lastId_ = 0;
std::unordered_map<GLenum, GLuint> currentBindings_;
static bool IsValidTarget_(GLenum target);
};
#endif //MOBILEGL_BUFFERSTATE_H
+2
View File
@@ -13,7 +13,9 @@ private:
std::unordered_map<GLenum, GLint> pixelStoreParams;
public:
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum SetPixelStoreInt(GLenum pname, GLint param);
GLint GetPixelStoreInt(GLenum pname);
};
+90 -2
View File
@@ -7,16 +7,22 @@
std::queue<GLenum> MG_State_T::glErrorQueue;
TextureState* MG_State_T::textureState = nullptr;
CommonState* MG_State_T::commonState = nullptr;
BufferState* MG_State_T::bufferState = nullptr;
VertexArrayState* MG_State_T::vertexArrayState = nullptr;
namespace MG_State {
void Init() {
MG_State_T::textureState = new TextureState();
MG_State_T::commonState = new CommonState();
MG_State_T::bufferState = new BufferState();
MG_State_T::vertexArrayState = new VertexArrayState();
}
void Destroy() {
delete MG_State_T::textureState;
delete MG_State_T::commonState;
delete MG_State_T::bufferState;
delete MG_State_T::vertexArrayState;
}
void SetError(GLenum error) {
@@ -34,7 +40,9 @@ namespace MG_State {
MG_State_T::glErrorQueue.pop();
return error;
}
// TODO: Take these functions apart into multiple files.
// Texture
GLenum BindTextureUnit(GLenum textureUnit) {
return MG_State_T::textureState->BindUnit(textureUnit);
@@ -83,7 +91,8 @@ namespace MG_State {
GLenum GetTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) {
return MG_State_T::textureState->GetLevelPropertyIntVector(target, level, pname, params);
}
// Common
GLenum MG_State::SetPixelStoreInt(GLenum pname, GLint param) {
return MG_State_T::commonState->SetPixelStoreInt(pname, param);
}
@@ -91,5 +100,84 @@ namespace MG_State {
GLint MG_State::GetPixelStoreInt(GLenum pname) {
return MG_State_T::commonState->GetPixelStoreInt(pname);
}
// Buffer
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr) {
return MG_State_T::bufferState->AcquireBufferMemory(target, access, mappedPtr);
}
GLenum ReleaseBufferMemory(GLenum target) {
return MG_State_T::bufferState->ReleaseBufferMemory(target);
}
GLenum CreateBuffer(GLuint* buffer) {
return MG_State_T::bufferState->Create(buffer);
}
GLenum CreateBuffers(GLsizei n, GLuint* buffers) {
return MG_State_T::bufferState->CreateN(n, buffers);
}
GLenum BindBuffer(GLenum target, GLuint buffer) {
if (target == GL_ELEMENT_ARRAY_BUFFER) {
auto* vao = MG_State_T::vertexArrayState->GetCurrentVAO();
if (!vao) return GL_INVALID_OPERATION;
vao->elementBuffer = (GLuint)buffer;
}
return MG_State_T::bufferState->Bind(target, buffer);
}
GLenum CommitBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
return MG_State_T::bufferState->CommitStorage(target, size, data, usage);
}
bool ValidateBufferHandle(GLuint buffer) {
return MG_State_T::bufferState->ValidateHandle(buffer);
}
void DeleteBuffer(GLuint buffer) {
return MG_State_T::bufferState->Delete(buffer);
}
GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params) {
return MG_State_T::bufferState->QueryPropertyIntVector(target, pname, params);
}
// VertexArray
GLenum BindVertexArray(GLuint array) {
return MG_State_T::vertexArrayState->Bind(array);
}
GLenum CreateVertexArray(GLuint* array) {
return MG_State_T::vertexArrayState->Create(array);
}
GLenum CreateVertexArrays(GLsizei n, GLuint* arrays) {
return MG_State_T::vertexArrayState->CreateN(n, arrays);
}
GLenum EnableVertexAttribArray(GLuint index) {
return MG_State_T::vertexArrayState->EnableAttrib(index);
}
GLenum DisableVertexAttribArray(GLuint index) {
return MG_State_T::vertexArrayState->DisableAttrib(index);
}
GLenum SetVertexAttributeLayout(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride,
const void* pointer) {
GLuint currentBuffer = MG_State_T::bufferState->GetCurrentBinding(GL_ARRAY_BUFFER);
return MG_State_T::vertexArrayState->SetAttribPointer(
index, size, type, normalized, stride, pointer, false, currentBuffer
);
}
GLenum SetVertexAttributeLayoutInt(GLuint index, GLint size, GLenum type,
GLsizei stride, const void* pointer) {
GLuint currentBuffer = MG_State_T::bufferState->GetCurrentBinding(GL_ARRAY_BUFFER);
return MG_State_T::vertexArrayState->SetAttribPointer(
index, size, type, GL_FALSE, stride, pointer, true, currentBuffer
);
}
}
+28 -1
View File
@@ -11,6 +11,8 @@ struct MG_State_T {
static std::queue<GLenum> glErrorQueue;
static TextureState* textureState;
static CommonState* commonState;
static BufferState* bufferState;
static VertexArrayState* vertexArrayState;
};
namespace MG_State {
@@ -35,9 +37,34 @@ namespace MG_State {
GLenum DeleteTexture(GLuint texture);
GLenum DeleteTextures(GLsizei n, const GLuint* textures);
GLenum GetTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params);
// Common
GLenum SetPixelStoreInt(GLenum pname, GLint param);
GLint GetPixelStoreInt(GLenum pname);
// Buffer
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr);
GLenum ReleaseBufferMemory(GLenum target);
GLenum CreateBuffer(GLuint* buffer);
GLenum CreateBuffers(GLsizei n, GLuint* buffers);
GLenum BindBuffer(GLenum target, GLuint buffer);
GLenum CommitBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
bool ValidateBufferHandle(GLuint buffer);
void DeleteBuffer(GLuint buffer);
GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params);
// VertexArray
GLenum CreateVertexArray(GLuint* array);
GLenum CreateVertexArrays(GLsizei n, GLuint* arrays);
GLenum BindVertexArray(GLuint array);
GLenum EnableVertexAttribArray(GLuint index);
GLenum DisableVertexAttribArray(GLuint index);
GLenum SetVertexAttributeLayout(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride,
const void* pointer);
GLenum SetVertexAttributeLayoutInt(GLuint index, GLint size, GLenum type,
GLsizei stride, const void* pointer);
}
+2 -3
View File
@@ -98,10 +98,9 @@ private:
static void ReverseBitOrder_(const GLubyte* src, GLubyte* dst, size_t size);
static GLubyte ReverseBits_(GLubyte b);
void SwapPixelBytes_(GLenum format, GLenum type, const GLubyte* src, GLubyte* dst);
GLenum CheckUploadingTexture2DValidity_(GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLenum format,
GLenum type, const void* data);
GLsizei width, GLsizei height, GLint border, GLenum format,
GLenum type, const void* data);
GLenum CheckUpdatingTextureRegion2DValidity_(GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLsizei width, GLsizei height, GLenum format,
GLenum type, const GLvoid* data);
@@ -0,0 +1,91 @@
//
// Created by BZLZHH on 2025/5/1.
//
// TODO: Add more gl error check for buffer state manager.
#include "VertexArrayState.h"
VertexArrayState::VertexArrayState() {
vaos_[0];
}
GLenum VertexArrayState::Create(GLuint* array) {
if (array == nullptr) return GL_INVALID_VALUE;
GLuint id = freeIds_.empty() ? ++lastId_ : *freeIds_.begin();
if (!freeIds_.empty()) {
freeIds_.erase(freeIds_.begin());
}
*array = id;
vaos_[id].generated = true;
return GL_NO_ERROR;
}
GLenum VertexArrayState::CreateN(GLsizei n, GLuint* arrays) {
if (n < 0) {
return GL_INVALID_VALUE;
}
if (n > 0 && arrays == nullptr) {
return GL_INVALID_VALUE;
}
for (GLsizei i = 0; i < n; ++i) {
if (GLenum error = Create(&arrays[i]); error != GL_NO_ERROR) {
return error;
}
}
return GL_NO_ERROR;
}
GLenum VertexArrayState::Bind(GLuint array) {
if (array != 0 && !vaos_.count(array)) return GL_INVALID_OPERATION;
currentVao_ = array;
return GL_NO_ERROR;
}
GLenum VertexArrayState::EnableAttrib(GLuint index) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
vaos_[currentVao_].attribs[index].enabled = true;
return GL_NO_ERROR;
}
GLenum VertexArrayState::DisableAttrib(GLuint index) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
vaos_[currentVao_].attribs[index].enabled = false;
return GL_NO_ERROR;
}
GLenum VertexArrayState::SetAttribPointer(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride,
const void* pointer, bool isInteger,
GLuint currentArrayBuffer) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
VertexAttribState state;
state.size = size;
state.type = type;
state.normalized = normalized;
state.stride = stride;
state.pointer = pointer;
state.buffer = currentArrayBuffer;
state.isInteger = isInteger;
vaos_[currentVao_].attribs[index] = state;
return GL_NO_ERROR;
}
GLuint VertexArrayState::GetBoundElementBuffer() {
auto it = vaos_.find(currentVao_);
return (it != vaos_.end()) ? it->second.elementBuffer : 0;
}
VertexArrayObject* VertexArrayState::GetCurrentVAO() {
auto it = vaos_.find(currentVao_);
return (it != vaos_.end()) ? &it->second : &vaos_.at(0);
}
@@ -0,0 +1,53 @@
//
// Created by BZLZHH on 2025/5/1.
//
#ifndef MOBILEGL_VERTEXARRAYSTATE_H
#define MOBILEGL_VERTEXARRAYSTATE_H
#define MOBILEGL_GLSTATE_H
#include "../../../Includes.h"
struct VertexAttribState {
bool enabled = false;
GLint size = 4;
GLenum type = GL_FLOAT;
GLboolean normalized = GL_FALSE;
GLsizei stride = 0;
const GLvoid* pointer = nullptr;
GLuint buffer = 0;
bool isInteger = false;
};
struct VertexArrayObject {
bool generated = false;
GLuint elementBuffer = 0;
std::unordered_map<GLuint, VertexAttribState> attribs;
};
class VertexArrayState {
public:
VertexArrayState();
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum Create(GLuint* array);
GLenum CreateN(GLsizei n, GLuint* arrays);
GLenum Bind(GLuint array);
GLenum EnableAttrib(GLuint index);
GLenum DisableAttrib(GLuint index);
GLenum SetAttribPointer(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride,
const void* pointer, bool isInteger,
GLuint currentArrayBuffer);
GLuint GetBoundElementBuffer();
VertexArrayObject* GetCurrentVAO();
private:
std::unordered_map<GLuint, VertexArrayObject> vaos_;
std::set<GLuint> freeIds_;
GLuint lastId_ = 0;
GLuint currentVao_ = 0;
};
#endif //MOBILEGL_VERTEXARRAYSTATE_H