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); }