[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
@@ -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