Archived
1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
skcblitz/framebuf.h

155 lines
4.5 KiB
C
Raw Permalink Normal View History

2025-09-02 14:43:36 +02:00
byte fb_init_int(uint *fbo, uint *fbtex, uint *rbo, byte linear) {
uint status;
glGenFramebuffers(1, fbo);
glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
glGenTextures(1, fbtex);
glBindTexture(GL_TEXTURE_2D, *fbtex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *fbtex, 0);
if(rbo) {
glGenRenderbuffers(1, rbo);
glBindRenderbuffer(GL_RENDERBUFFER, *rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 16, 16);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *rbo);
}
if((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
loge(LOG_GFX, STR_FBO_INCOMPLETE, *fbo, status);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteTextures(1, fbtex);
glDeleteFramebuffers(1, fbo);
if(rbo) {
glDeleteRenderbuffers(1, rbo);
}
return 0;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
gdr.fb_mem += 16 * 16 * 4;
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
return 1;
}
byte fb_init_sys(uint *fbo, uint *fbtex) {
if(fb_init_int(fbo, fbtex, NULL, 0)) {
logd(LOG_GFX, STR_FBO_ADDED, *fbo, *fbtex);
gdr.fb_loaded += 1;
return 1;
}
return 0;
}
fbo_t *fb_init(uint *fbo, uint *fbtex, uint *rbo, window_t *resize, byte linear) {
fbo_t *bind;
if(!fb_init_int(fbo, fbtex, rbo, linear))
return NULL;
sys_assert(bind = (fbo_t*)tbl_push(&gdr.framebufs));
bind->fbo = fbo;
bind->tex = fbtex;
bind->rbo = rbo;
bind->resize = resize;
bind->linear = linear;
bind->xsize = 0;
bind->ysize = 0;
gdr.fb_loaded += 1;
if(rbo)
logd(LOG_GFX, STR_FBO_ADDED_RBO, *fbo, *fbtex, *rbo);
else
logd(LOG_GFX, STR_FBO_ADDED, *fbo, *fbtex);
return bind;
}
void fb_resize_int(uint fbtex, int px, int py, int x, int y) {
gdr.fb_mem -= px * py * 4;
glBindTexture(GL_TEXTURE_2D, fbtex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
gdr.fb_mem += x * y * 4;
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
}
byte fb_resize(fbo_t *buf, window_t *resize) {
if(!(buf->resize) || (buf->resize != resize))
return 0;
glBindTexture(GL_TEXTURE_2D, *(buf->tex));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, resize->fb_x, resize->fb_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if(buf->rbo) {
glBindRenderbuffer(GL_RENDERBUFFER, *(buf->rbo));
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, resize->fb_x, resize->fb_y);
}
gdr.fb_mem -= buf->xsize * buf->ysize * 4;
gdr.fb_mem += (buf->xsize = resize->fb_x) * (buf->ysize = resize->fb_y) * 4;
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
return 1;
}
int fb_reconfig(window_t *resize) {
int done = 0;
ulong iter = 0;
fbo_t *buf;
while(buf = tbl_iter(&gdr.framebufs, &iter)) {
done += (int)fb_resize(buf, resize);
}
// logd(LOG_GFX, STR_FBO_RESIZE, done);
return done;
}
void fb_size_int(uint tex, uint rbo, int x, int y) {
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if(rbo) {
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, x, y);
}
}
byte fb_size(fbo_t *buf, int x, int y) {
fb_size_int(*(buf->tex), buf->rbo ? *(buf->rbo) : 0, x, y);
gdr.fb_mem -= buf->xsize * buf->ysize * 4;
gdr.fb_mem += (buf->xsize = x) * (buf->ysize = y) * 4;
gdr.fb_peak = gdr.fb_mem > gdr.fb_peak ? gdr.fb_mem : gdr.fb_peak;
}
void fb_delete(uint *fbo, uint *fbtex) {
if(*fbo) {
glDeleteTextures(1, fbtex);
glDeleteFramebuffers(1, fbo);
logd(LOG_GFX, STR_FBO_DELETED, *fbo, *fbtex);
*fbo = 0;
*fbtex = 0;
gdr.fb_loaded -= 1;
}
}
byte fb_unload(fbo_t *buf) {
if(!(*(buf->fbo))) {
return 0;
}
glDeleteTextures(1, buf->tex);
glDeleteFramebuffers(1, buf->fbo);
if(buf->rbo) {
glDeleteRenderbuffers(1, buf->rbo);
logd(LOG_GFX, STR_FBO_DELETED_RBO, *(buf->fbo), *(buf->tex), *(buf->rbo));
*(buf->rbo) = 0;
}
else {
logd(LOG_GFX, STR_FBO_DELETED, *(buf->fbo), *(buf->tex));
}
*(buf->fbo) = 0;
*(buf->tex) = 0;
gdr.fb_loaded -= 1;
return 1;
}
void fb_remove(fbo_t *buf) {
if(fb_unload(buf)) {
tbl_pop(&gdr.framebufs, buf);
}
}
int fb_clear() {
return tbl_clear_func(&gdr.framebufs, (clear_func*)fb_unload);
}