Files
korenkonder_ReDIVA/src/CRE/ogl_buffer_object.cpp
T
2026-06-12 18:49:01 +03:00

365 lines
8.4 KiB
C++

/*
by korenkonder
GitHub/GitLab: korenkonder
*/
#include "ogl_buffer_object.hpp"
#include "../KKdLib/obj.hpp"
#include "mdl/disp_manager.hpp"
#include "gl_state.hpp"
#include "render_context.hpp"
struct BufObjMgr {
int32_t vb_peak_size;
int32_t vb_all_size;
int32_t ib_peak_size;
int32_t ib_all_size;
};
BufObjMgr bufobj_mgr;
// Added
IndexBuffer::IndexBuffer() : ib() {
}
// Added
bool IndexBuffer::create(uint32_t size, const void* buf) {
if (!size)
return false;
ib = create_index_buffer(size, buf);
return true;
}
#if SHARED_OBJECT_BUFFER
// Added
void IndexBuffer::create(GLuint in_ib) {
ib = in_ib;
}
#endif
// Added
void IndexBuffer::destroy() {
free_index_buffer(ib);
ib = 0;
}
#if SHARED_OBJECT_BUFFER
// Added
void IndexBuffer::destroy_shared() {
ib = 0;
}
#endif
// Added
GLuint IndexBuffer::get_glib() const {
return ib;
}
// 0x1404615C0
#if SHARED_OBJECT_BUFFER
VertexBuffer::VertexBuffer() : num_flip_chain(), vb(),
flip_index(), target(GL_ARRAY_BUFFER), vb_size(), vb_offset() {
#else
VertexBuffer::VertexBuffer() : num_flip_chain(), vb(),
flip_index(), target(GL_ARRAY_BUFFER), vb_size() {
#endif
}
// 0x1404615E0
VertexBuffer::~VertexBuffer() {
destroy();
}
// 0x140461650
bool VertexBuffer::create(uint32_t size, const void* buf, uint32_t num_flip, GL::BufferUsage usage) {
if (!size || num_flip > VertexBuffer::NUM_FLIP_MAX)
return false;
num_flip_chain = num_flip;
flip_index = 0;
vb_size = size;
#if SHARED_OBJECT_BUFFER
vb_offset = 0;
#endif
for (uint32_t i = 0; i < num_flip; i++) {
vb[i] = create_vertex_buffer(size, buf, usage);
if (!vb[i]) {
destroy();
return false;
}
}
return true;
}
#if SHARED_OBJECT_BUFFER
// Added
void VertexBuffer::create(GLuint in_vb, uint32_t size, uint32_t offset) {
destroy_shared();
if (size) {
num_flip_chain = 1;
flip_index = 0;
vb[0] = in_vb;
vb_size = size;
vb_offset = offset;
bufobj_mgr.vb_all_size += size;
bufobj_mgr.vb_peak_size = max_def(bufobj_mgr.vb_peak_size, bufobj_mgr.vb_all_size);
}
}
#endif
// 0x140461870
void VertexBuffer::destroy() {
for (uint32_t i = 0; i < num_flip_chain; i++) {
free_vertex_buffer(vb[i]);
vb[i] = 0;
}
num_flip_chain = 0;
flip_index = 0;
vb_size = 0;
#if SHARED_OBJECT_BUFFER
vb_offset = 0;
#endif
}
#if SHARED_OBJECT_BUFFER
// Added
void VertexBuffer::destroy_shared() {
for (uint32_t i = 0; i < num_flip_chain; i++)
vb[i] = 0;
bufobj_mgr.vb_all_size -= vb_size;
num_flip_chain = 0;
flip_index = 0;
vb_size = 0;
vb_offset = 0;
}
#endif
// 0x1404618E0
void VertexBuffer::flip() {
if (++flip_index >= num_flip_chain)
flip_index = 0;
}
// 0x140461A20
GLuint VertexBuffer::get_glvb() const {
if (flip_index < num_flip_chain)
return vb[flip_index];
return 0;
}
// Missing
GLuint VertexBuffer::get_glvb_at(uint32_t index) const {
if (index < num_flip_chain)
return vb[index];
return 0;
}
// Added
uint32_t VertexBuffer::get_glvb_offset() const {
#if SHARED_OBJECT_BUFFER
if (vb[0])
return vb_offset;
#endif
return 0;
}
// 0x140461A40
uint32_t VertexBuffer::get_num_flip_chain(uint32_t index) const {
return num_flip_chain;
}
// 0x140461A50
uint32_t VertexBuffer::get_size() const {
if (vb[0])
return vb_size;
return 0;
}
// 0x140461AE0
GLenum VertexBuffer::get_target() const {
return GL_ARRAY_BUFFER;
}
// 0x1404616F0
GLuint create_index_buffer(uint32_t size, const void* buf) {
GLuint ib = 0;
glGenBuffers(1, &ib);
gl_state.bind_element_array_buffer(ib);
if (GLAD_GL_VERSION_4_4)
glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, size, buf, 0);
else
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, buf, GL_STATIC_DRAW);
gl_state.bind_element_array_buffer(0);
if (glGetError()) {
glDeleteBuffers(1, &ib);
return 0;
}
bufobj_mgr.ib_all_size += size;
bufobj_mgr.ib_peak_size = max_def(bufobj_mgr.ib_peak_size, bufobj_mgr.ib_all_size);
return ib;
}
// 0x140461900
void free_index_buffer(GLuint ib) {
if (!ib)
return;
extern render_context* rctx_ptr;
rctx_ptr->disp_manager->remove_index_buffer(ib);
GLint size = 0;
if (GLAD_GL_VERSION_4_5)
glGetNamedBufferParameteriv(ib, GL_BUFFER_SIZE, &size);
else {
gl_state.bind_element_array_buffer(ib);
glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
gl_state.bind_element_array_buffer(0);
}
bufobj_mgr.ib_all_size -= size;
glDeleteBuffers(1, &ib);
glGetError();
}
// 0x1404617B0
GLuint create_vertex_buffer(uint32_t size, const void* buf, GL::BufferUsage usage) {
GLuint vb = 0;
glGenBuffers(1, &vb);
gl_state.bind_array_buffer(vb);
if (GLAD_GL_VERSION_4_4 && usage != GL::BUFFER_USAGE_STREAM) {
GLbitfield flags = usage == GL::BUFFER_USAGE_DYNAMIC
? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0;
glBufferStorage(GL_ARRAY_BUFFER, size, buf, flags);
}
else
glBufferData(GL_ARRAY_BUFFER, size, buf, GL::BufferUsageToGLenum(usage));
gl_state.bind_array_buffer(0);
if (glGetError()) {
glDeleteBuffers(1, &vb);
return 0;
}
bufobj_mgr.vb_all_size += size;
bufobj_mgr.vb_peak_size = max_def(bufobj_mgr.vb_peak_size, bufobj_mgr.vb_all_size);
return vb;
}
// 0x140461990
void free_vertex_buffer(GLuint vb) {
if (!vb)
return;
extern render_context* rctx_ptr;
rctx_ptr->disp_manager->remove_vertex_buffer(vb);
GLint size = 0;
if (GLAD_GL_VERSION_4_5)
glGetNamedBufferParameteriv(vb, GL_BUFFER_SIZE, &size);
else {
gl_state.bind_array_buffer(vb);
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
gl_state.bind_array_buffer(0);
}
bufobj_mgr.vb_all_size -= size;
glDeleteBuffers(1, &vb);
glGetError();
}
// 0x140461AF0
void get_vertex_buffer_memory_info(int32_t* vb_all_size, int32_t* vb_peak_size) {
if (vb_all_size)
*vb_all_size = bufobj_mgr.vb_all_size;
if (vb_peak_size)
*vb_peak_size = bufobj_mgr.vb_peak_size;
}
// 0x140469640
uint32_t get_vertex_size(uint32_t format, uint32_t compression) {
uint32_t size = 0;
switch (compression) {
case 0:
default:
if (format & OBJ_VERTEX_POSITION)
size += 12;
if (format & OBJ_VERTEX_NORMAL)
size += 12;
if (format & OBJ_VERTEX_TANGENT)
size += 16;
if (format & OBJ_VERTEX_BINORMAL)
size += 12;
if (format & OBJ_VERTEX_TEXCOORD0)
size += 8;
if (format & OBJ_VERTEX_TEXCOORD1)
size += 8;
if (format & OBJ_VERTEX_TEXCOORD2)
size += 8;
if (format & OBJ_VERTEX_TEXCOORD3)
size += 8;
if (format & OBJ_VERTEX_COLOR0)
size += 16;
if (format & OBJ_VERTEX_COLOR1)
size += 16;
if (format & OBJ_VERTEX_BONE_DATA)
size += 24;
if (format & OBJ_VERTEX_UNKNOWN)
size += 16;
break;
case 1: // Added
if (format & OBJ_VERTEX_POSITION)
size += 12;
if (format & OBJ_VERTEX_NORMAL)
size += 8;
if (format & OBJ_VERTEX_TANGENT)
size += 8;
if (format & OBJ_VERTEX_TEXCOORD0)
size += 4;
if (format & OBJ_VERTEX_TEXCOORD1)
size += 4;
if (format & OBJ_VERTEX_TEXCOORD2)
size += 4;
if (format & OBJ_VERTEX_TEXCOORD3)
size += 4;
if (format & OBJ_VERTEX_COLOR0)
size += 8;
if (format & OBJ_VERTEX_BONE_DATA)
size += 16;
break;
case 2: // Added
if (format & OBJ_VERTEX_POSITION)
size += 12;
if (format & OBJ_VERTEX_NORMAL)
size += 4;
if (format & OBJ_VERTEX_TANGENT)
size += 4;
if (format & OBJ_VERTEX_TEXCOORD0)
size += 4;
if (format & OBJ_VERTEX_TEXCOORD1)
size += 4;
if (format & OBJ_VERTEX_TEXCOORD2)
size += 4;
if (format & OBJ_VERTEX_TEXCOORD3)
size += 4;
if (format & OBJ_VERTEX_COLOR0)
size += 8;
if (format & OBJ_VERTEX_BONE_DATA)
size += 8;
break;
}
return size;
}