From 99d49b59e99cc94d18efd3ff0e33a25d7356bae9 Mon Sep 17 00:00:00 2001 From: onelin Date: Wed, 17 Dec 2025 13:48:51 +0100 Subject: Add framebuffer resizing --- src/window.c | 128 +++++++++++++++++++++++++---------------------------------- 1 file changed, 55 insertions(+), 73 deletions(-) (limited to 'src/window.c') diff --git a/src/window.c b/src/window.c index 36c1612..142e8bd 100644 --- a/src/window.c +++ b/src/window.c @@ -15,6 +15,7 @@ #include #include +#include extern Instance* GLOBAL_PLATFORM; @@ -68,35 +69,58 @@ Window* Window_new(const struct Platform* p, const char *restrict title, Window_ void window_reset_cameras(Window* w, RenderTargets* restrict targets) { - // Question, would it be better to check both callbacks and continue early, - // instead of resizing the texture first, then check the camera callback? + usize b_ofst = 0; for (usize i = 0; i < targets->framebuffer_len; i++) { - //if (targets->framebuffer_size_callback[i] == NULL) continue; + ivec3 newsz; + // Set last dimension to 0 to ensure 2d + newsz[2] = 0; + // Well aware that we copy a smaller sized vec into a larger one, thank you. + glm_ivec2_copy(w->windowsize, newsz); + + const i8 num_textures = targets->framebuffer_parameters[i].num_textures; + const i8 num_renderbuffers = targets->framebuffer_parameters[i].num_renderbuffers; + + // Change framebuffer & attached buffers dimensions, if framebuffer resize callback exists + if (targets->framebuffer_size_callback[i] != NULL) { + targets->framebuffer_size_callback[i](&newsz, w->windowsize); + + // as far as I can tell from the OpenGL docs, it should be safe to just + // delete framebuffers and attached buffers + u32 *buffer = &targets->buffer[b_ofst]; + if (num_textures != 0) { + r_destroy_textures(w->context, buffer, targets->framebuffer_parameters[i].num_textures); + // Move buf ptr + } + + if (num_renderbuffers != 0) { + // renderbuffer(s) should be located after "textures", so their index + // starts at num_textures. + r_destroy_renderbuffers(w->context, &buffer[num_textures], targets->framebuffer_parameters[i].num_renderbuffers); + } + + r_destroy_framebuffers(w->context, &targets->framebuffer[i], 1); + - //ivec2 newsz; - //targets->framebuffer_size_callback[i](&newsz, w->windowsize); + // TODO: Re-Create framebuffers and related buffers with new sizes. + glm_ivec3_copy(newsz, targets->framebuffer_parameters[i].dimensions); - // Destroy & Create framebuffers (and related buffers?) + r_create_framebuffers(w->context, &targets->framebuffer[i], 1); + + r_setup_framebuffer(w->context, targets->framebuffer[i], + targets->framebuffer_parameters[i], + buffer, + &targets->buffer_parameters[b_ofst]); + } + + // Reset camera using callback (if any) + if (targets->camera_reset_callback[i] != NULL) { + targets->camera_reset_callback[i](targets->cam[i], newsz); + } - if (targets->camera_reset_callback[i] == NULL) continue; - targets->camera_reset_callback[i](targets->cam[i], w->windowsize); + b_ofst += num_textures + num_renderbuffers; } } -//void window_reset_texture_sizes(Window* w, RenderTargets* restrict targets) { -// // Question, would it be more efficient to just wipe all of them at once -// // instead of doing this? Not all are necessarily deleted. -// for (usize i = 0; i < targets->texture_len; i++) { -// if (targets->framebuffer_size_callback[i] == NULL) continue; -// -// ivec2 newsz; -// targets->framebuffer_size_callback[i](&newsz, w->windowsize); -// -// r_destroy_framebuffers(w->context, targets->framebuffer, 1); -// r_create_framebuffers(w->context, &targets->framebuffer[i], &targets->framebuffer_parameters[i].framebuffer_type, &newsz, 1); -// } -//} - void get_mousepos(double *x, double *y) { Window* w = GLOBAL_PLATFORM->window; @@ -133,6 +157,7 @@ void window_init_renderstack(Window *restrict w, sizeof(*t->framebuffer) * num_fbuf + sizeof(*t->framebuffer_parameters) * num_fbuf + sizeof(*t->cam) * num_fbuf + + sizeof(*t->framebuffer_size_callback) * num_fbuf + sizeof(*t->camera_reset_callback) * num_fbuf + sizeof(*t->buffer) * num_buf + sizeof(*t->buffer_parameters) * num_buf @@ -152,6 +177,7 @@ void window_init_renderstack(Window *restrict w, ADVANCE_PTR(framebuffer, num_fbuf); ADVANCE_PTR(framebuffer_parameters, num_fbuf); ADVANCE_PTR(cam, num_fbuf); + ADVANCE_PTR(framebuffer_size_callback, num_fbuf); ADVANCE_PTR(camera_reset_callback, num_fbuf); ADVANCE_PTR(buffer, num_buf); ADVANCE_PTR(buffer_parameters, num_buf); @@ -167,59 +193,15 @@ void window_init_renderstack(Window *restrict w, usize buffer_offset = 0; for (usize fb_idx = 0; fb_idx < num_fbuf; fb_idx++) { - // Count textures & renderbuffers - u32 num_textures = 0; - u32 num_renderbuffers = 0; - for (i32 i = 0; i < t->framebuffer_parameters[fb_idx].num_attached_buffers; i++) { - switch (BUFFERPARAMETER_GET_TYPE(t->buffer_parameters[buffer_offset + i])) { - case BufferType_frame: - UNIMPLEMENTED; - case BufferType_texture: - num_textures++; - break; - case BufferType_render: - num_renderbuffers++; - break; - case BufferType_buffer: - UNIMPLEMENTED; - default: - UNIMPLEMENTED; - } - } - - // Create `num_attached_buffers` identical buffers - r_create_textures(w->context, &t->buffer[buffer_offset], - &t->buffer_parameters[buffer_offset], - &t->framebuffer_parameters[fb_idx].dimensions, - num_textures); - - r_create_renderbuffers(w->context, &t->buffer[buffer_offset + num_textures], - &t->buffer_parameters[buffer_offset + num_textures], - &t->framebuffer_parameters[fb_idx].dimensions, - num_renderbuffers); - - r_attach_buffers(w->context, - t->framebuffer[fb_idx], + r_setup_framebuffer(w->context, t->framebuffer[fb_idx], + t->framebuffer_parameters[fb_idx], &t->buffer[buffer_offset], - &t->buffer_parameters[buffer_offset], - t->framebuffer_parameters[fb_idx].num_attached_buffers); - - //if (BUFFERPARAMETER_GET_TYPE(buffer_params[i]) != BufferType_texture) continue; - //u32 texture_type = BUFFERPARAMETER_GET_PARAMETER(buffer_params[i]); - - //usize span = 0; - //while ( - // (i + span < targets->buffer_len) && - // (BUFFERPARAMETER_GET_TYPE(buffer_params[i + span]) == BufferType_texture) && - // (buffer_params[i + span].buffer_param & 3) == textureType - //) { - // span++; - //} - //if (span == 0) continue; - //r_create_textures(w->context, &targets->buffer[i], texture_type, texturesizes, span); + &t->buffer_parameters[buffer_offset]); + + buffer_offset += + t->framebuffer_parameters[fb_idx].num_textures + + t->framebuffer_parameters[fb_idx].num_renderbuffers; } - //r_create_renderbuffers(c, targets->renderbuffer, renderbuffertypes, renderbuffersizes, targets->renderbuffer_len); - // Skip `texture` (??) w->render_targets = t; } -- cgit v1.3