101 lines
2.8 KiB
C
101 lines
2.8 KiB
C
|
|
int buf_init_int(byte dynamic, uint *vbo, uint *vao, const float *verts, uint size, int stride, va_list ap) {
|
|
int elems;
|
|
int pos;
|
|
int idx = 0;
|
|
glGenVertexArrays(1, vao);
|
|
glGenBuffers(1, vbo);
|
|
glBindBuffer(GL_ARRAY_BUFFER, *vbo);
|
|
glBufferData(GL_ARRAY_BUFFER, size, verts, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
|
gdr.buf_mem += size;
|
|
gdr.buf_peak = gdr.buf_mem > gdr.buf_peak ? gdr.buf_mem : gdr.buf_peak;
|
|
glBindVertexArray(*vao);
|
|
for(pos = 0; pos < stride; pos += elems) {
|
|
elems = va_arg(ap, int);
|
|
glVertexAttribPointer(idx, elems, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)(pos * sizeof(float)));
|
|
glEnableVertexAttribArray(idx++);
|
|
}
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
return idx;
|
|
}
|
|
|
|
void buf_init_sys(uint *vbo, uint *vao, const float *verts, uint size, int stride, ...) {
|
|
va_list ap;
|
|
va_start(ap, stride);
|
|
buf_init_int(0, vbo, vao, verts, size, stride, ap);
|
|
logd(LOG_GFX, STR_BUF_ILOADED, size, stride, *vbo, *vao);
|
|
va_end(ap);
|
|
}
|
|
|
|
buf_t *buf_init(byte dynamic, uint *vbo, uint *vao, const float *verts, uint size, int stride, ...) {
|
|
va_list ap;
|
|
va_start(ap, stride);
|
|
int idx;
|
|
buf_t *bind;
|
|
sys_assert(bind = (buf_t*)tbl_push(&gdr.buffers));
|
|
idx = buf_init_int(dynamic, vbo, vao, verts, size, stride, ap);
|
|
bind->vao = vao;
|
|
bind->vbo = vbo;
|
|
bind->size = size;
|
|
bind->stride = stride;
|
|
bind->groups = idx;
|
|
bind->dynamic = dynamic;
|
|
gdr.buf_loaded += 1;
|
|
logt(LOG_GFX, STR_BUF_LOADED, size, stride, *vbo, *vao);
|
|
va_end(ap);
|
|
return bind;
|
|
}
|
|
|
|
void buf_data(buf_t *buf, const float *verts, uint size) {
|
|
size *= ((uint)buf->stride) * sizeof(float);
|
|
glBindBuffer(GL_ARRAY_BUFFER, *(buf->vbo));
|
|
glBufferData(GL_ARRAY_BUFFER, size, verts, buf->dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
if(buf->size != size) {
|
|
logt(LOG_GFX, STR_BUF_RESIZED, *(buf->vbo), *(buf->vao), buf->size, size, buf->stride);
|
|
gdr.buf_mem -= buf->size;
|
|
gdr.buf_mem += buf->size = size;
|
|
gdr.buf_peak = gdr.buf_mem > gdr.buf_peak ? gdr.buf_mem : gdr.buf_peak;
|
|
}
|
|
}
|
|
|
|
void buf_delete(uint *vbo, uint *vao) {
|
|
if(*vbo) {
|
|
glDeleteBuffers(1, vbo);
|
|
glDeleteVertexArrays(1, vao);
|
|
logd(LOG_GFX, STR_BUF_IUNLOADED, *vbo, *vao);
|
|
*vbo = 0;
|
|
*vao = 0;
|
|
}
|
|
}
|
|
|
|
byte buf_unload(buf_t *buf) {
|
|
if(!(*(buf->vbo))) {
|
|
return 0;
|
|
}
|
|
glDeleteBuffers(1, buf->vbo);
|
|
glDeleteVertexArrays(1, buf->vao);
|
|
gdr.buf_mem -= buf->size;
|
|
logt(LOG_GFX, STR_BUF_UNLOADED, buf->size, buf->stride, *(buf->vbo), *(buf->vao));
|
|
*(buf->vbo) = 0;
|
|
*(buf->vao) = 0;
|
|
return 1;
|
|
}
|
|
|
|
void buf_remove(buf_t *buf) {
|
|
if(buf_unload(buf)) {
|
|
// tbl_pop(&gdr.buffers, buf);
|
|
gdr.buf_loaded -= 1;
|
|
}
|
|
}
|
|
|
|
void buf_destroy(buf_t *buf) {
|
|
if(buf_unload(buf)) {
|
|
tbl_pop(&gdr.buffers, buf);
|
|
gdr.buf_loaded -= 1;
|
|
}
|
|
}
|
|
|
|
int buf_clear() {
|
|
return tbl_clear_func(&gdr.buffers, (clear_func*)buf_remove);
|
|
}
|