[Feat] (VertexArray): Implement renaming for VAO.

This commit is contained in:
BZLZHH
2025-05-11 09:32:11 +08:00
parent ba339ca182
commit d0b8777249
5 changed files with 75 additions and 5 deletions
@@ -7,7 +7,7 @@
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);
GLenum result = MG_State::GenVertexArraysNames(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));
+4
View File
@@ -214,6 +214,10 @@ namespace MG_State {
return MG_State_T::vertexArrayState->CreateN(n, arrays);
}
GLenum GenVertexArraysNames(GLsizei n, GLuint* arrays) {
return MG_State_T::vertexArrayState->GenNameN(n, arrays);
}
GLenum EnableVertexAttribArray(GLuint index) {
return MG_State_T::vertexArrayState->EnableAttrib(index);
}
+1
View File
@@ -71,6 +71,7 @@ namespace MG_State {
// VertexArray
GLenum CreateVertexArray(GLuint* array);
GLenum CreateVertexArrays(GLsizei n, GLuint* arrays);
GLenum GenVertexArraysNames(GLsizei n, GLuint* arrays);
GLenum BindVertexArray(GLuint array);
GLenum EnableVertexAttribArray(GLuint index);
GLenum DisableVertexAttribArray(GLuint index);
@@ -10,6 +10,37 @@ VertexArrayState::VertexArrayState() {
vaos_[0];
}
GLenum VertexArrayState::GenName(GLuint *array) {
MG_Util::Debug::LogD("MG_State: VAO: GenName");
if (!array)
return GL_INVALID_VALUE;
GLuint id;
if (freeIds_.empty()) {
id = ++lastId_;
} else {
id = *freeIds_.begin();
freeIds_.erase(freeIds_.begin());
}
*array = id;
MG_Util::Debug::LogD("MG_State: VAO: Generated new name %d", id);
return GL_NO_ERROR;
}
GLenum VertexArrayState::GenNameN(GLsizei n, GLuint* arrays) {
MG_Util::Debug::LogD("MG_State: VAO: GenNameN called with n=%d", n);
if (n < 0)
return GL_INVALID_VALUE;
for (GLsizei i = 0; i < n; ++i) {
GLenum result = GenName(&arrays[i]);
if (result != GL_NO_ERROR) {
MG_Util::Debug::LogE("MG_State: VAO: GenNameN failed at index %d with error 0x%x", i, result);
return result;
}
}
MG_Util::Debug::LogD("MG_State: VAO: GenNameN created %d names", n);
return GL_NO_ERROR;
}
GLenum VertexArrayState::Create(GLuint* array) {
if (array == nullptr) return GL_INVALID_VALUE;
@@ -41,13 +72,41 @@ GLenum VertexArrayState::CreateN(GLsizei n, GLuint* arrays) {
}
GLenum VertexArrayState::Bind(GLuint array) {
if (array != 0 && !vaos_.count(array)) return GL_INVALID_OPERATION;
MG_Util::Debug::LogD("MG_State: VAO: Bind called for %u", array);
if (array != 0) {
if (!ValidateGeneratedName(array)) {
MG_Util::Debug::LogE("MG_State: VAO: Bind invalid name %u", array);
return GL_INVALID_OPERATION;
}
auto& vao = vaos_[array];
if (!vao.generated) {
MG_Util::Debug::LogD("MG_State: VAO: Creating VAO %u during bind", array);
vao.generated = true;
}
}
currentVao_ = array;
MG_Util::Debug::LogD("MG_State: VAO: Bound to %u", array);
return GL_NO_ERROR;
}
bool VertexArrayState::ValidateGeneratedName(GLuint array) {
if (array == 0)
return true;
bool inFreeList = freeIds_.count(array) > 0;
bool valid = (array <= lastId_) && !inFreeList;
MG_Util::Debug::LogD("MG_State: VAO: ValidateGeneratedName %u: %d", array, valid);
return valid;
}
bool VertexArrayState::ValidateAllocatedHandle(GLuint array) {
bool exists = vaos_.count(array) && vaos_[array].generated;
MG_Util::Debug::LogD("MG_State: VAO: ValidateAllocatedHandle %u: %d", array, exists);
return exists;
}
GLenum VertexArrayState::EnableAttrib(GLuint index) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
GetCurrentVAO()->attribs[index].enabled = true;
MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled);
@@ -55,7 +114,8 @@ GLenum VertexArrayState::EnableAttrib(GLuint index) {
}
GLenum VertexArrayState::DisableAttrib(GLuint index) {
if (currentVao_ == 0) return GL_INVALID_OPERATION;
if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
GetCurrentVAO()->attribs[index].enabled = false;
MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled);
@@ -66,7 +126,8 @@ 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 (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
VertexAttribState state;
@@ -30,6 +30,8 @@ public:
VertexArrayState();
// Return: the validity of the operation, according to OpenGL 3 standard
GLenum GenName(GLuint* array);
GLenum GenNameN(GLsizei n, GLuint* arrays);
GLenum Create(GLuint* array);
GLenum CreateN(GLsizei n, GLuint* arrays);
GLenum Bind(GLuint array);
@@ -42,6 +44,8 @@ public:
GLuint GetBoundElementBuffer();
VertexArrayObject* GetCurrentVAO();
bool ValidateGeneratedName(GLuint array);
bool ValidateAllocatedHandle(GLuint array);
GLuint currentVao_ = 0;
std::unordered_map<GLuint, VertexArrayObject> vaos_;