summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
authoronelin <oscar@nelin.dk>2025-12-17 12:48:51 +0000
committeronelin <oscar@nelin.dk>2025-12-18 21:14:22 +0000
commit99d49b59e99cc94d18efd3ff0e33a25d7356bae9 (patch)
treed60fdcdf59c7f75307b6f57c3ac8734999425971 /src/window.c
parent261d33c72095a2abd98177f88ebb24fe205a042f (diff)
Add framebuffer resizing
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c126
1 files changed, 54 insertions, 72 deletions
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 <GLFW/glfw3.h>
#include <cglm/ivec2.h>
+#include <cglm/ivec3.h>
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);
- //ivec2 newsz;
- //targets->framebuffer_size_callback[i](&newsz, w->windowsize);
+ const i8 num_textures = targets->framebuffer_parameters[i].num_textures;
+ const i8 num_renderbuffers = targets->framebuffer_parameters[i].num_renderbuffers;
- // Destroy & Create framebuffers (and related buffers?)
+ // 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);
- if (targets->camera_reset_callback[i] == NULL) continue;
- targets->camera_reset_callback[i](targets->cam[i], 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);
+
+
+ // TODO: Re-Create framebuffers and related buffers with new sizes.
+ glm_ivec3_copy(newsz, targets->framebuffer_parameters[i].dimensions);
+
+ 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);
+ }
+
+ 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]);
+ &t->buffer_parameters[buffer_offset]);
- //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);
+ 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;
}