diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/daw.c | 27 | ||||
| -rw-r--r-- | src/include/daw/rendering.h | 55 | ||||
| -rw-r--r-- | src/rendering.c | 27 | ||||
| -rw-r--r-- | src/window.c | 126 |
4 files changed, 132 insertions, 103 deletions
@@ -248,17 +248,17 @@ i32 engine_run(Instance* p, StateType initial_state, void* state_arg) { ivec2 wsz; window_get_size(&wsz); u32 t[] = { - BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_TEXTURE_2D | BUFFERPARAMETER_FMT_RGB8), + BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_FMT_RGB8), // The depth buffer could also be a texture like so: // BUFFERPARAMETER_SET_PARAMETER( // BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), - // BUFFERPARAMETER_TEXTURE_2D | BUFFERPARAMETER_FMT_DEPTH32 + // BUFFERPARAMETER_FMT_DEPTH32 // ), - BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_render), BUFFERPARAMETER_RENDERBUFFER_DEPTH | BUFFERPARAMETER_FMT_DEPTH32F), + BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_render), BUFFERPARAMETER_FMT_DEPTH32F), }; FramebufferParameters p[] = { - {.num_attached_buffers = sizeof(t) / sizeof(t[0]), .dimensions = {wsz[0], wsz[1], 0}}, + {.num_textures = 1, .num_renderbuffers = 1, .dimensions = {wsz[0], wsz[1], 0}}, }; window_init_renderstack(w, 1, sizeof(t) / sizeof(t[0]), p, t); //w->render_targets->cam[0] = &default_renderbuffer_camera; @@ -342,13 +342,22 @@ i32 engine_run(Instance* p, StateType initial_state, void* state_arg) { // Create only 1 additional framebuffer, in addition to the default // one. This is used to render a texture that is represented as a quad // on the default framebuffer. - FramebufferParameters fb_params[] = { - {.num_attached_buffers = 1, {200,200}}, - }; + ivec2 wsz; + window_get_size(&wsz); u32 t[] = { - BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_TEXTURE_2D) + BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_FMT_RGB8), + + // The depth buffer could also be a texture like so: + // BUFFERPARAMETER_SET_PARAMETER( + // BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), + // BUFFERPARAMETER_FMT_DEPTH32 + // ), + BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_render), BUFFERPARAMETER_FMT_DEPTH32F), + }; + FramebufferParameters p[] = { + {.num_textures = 1, .num_renderbuffers = 1, .dimensions = {wsz[0], wsz[1], 0}}, }; - window_init_renderstack(w, 1, 1, fb_params, t); + window_init_renderstack(w, 1, sizeof(t) / sizeof(t[0]), p, t); //w->render_targets->cam[0] = &default_camera; } diff --git a/src/include/daw/rendering.h b/src/include/daw/rendering.h index 530a8e0..70b1566 100644 --- a/src/include/daw/rendering.h +++ b/src/include/daw/rendering.h @@ -264,26 +264,39 @@ typedef enum { // TODO: Change `2` once we add support for more formats -#define BUFFERPARAMETER_FMT_GET(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & (((1 << 8) - 1) << 2)) - #define BUFFERPARAMETER_FMT_IS_COLOR(bufferparam) \ ((BUFFERPARAMETER_GET_PARAMETER(bufferparam) & BUFFERPARAMETER_FMT_COLOR_MASK) != 0) #define BUFFERPARAMETER_FMT_IS_DEPTH_OR_STENCIL(bufferparam) \ ((BUFFERPARAMETER_GET_PARAMETER(bufferparam) & BUFFERPARAMETER_FMT_DEPTH_STENCIL_MASK) != 0) +// The textures and renderbuffers must be contigous in the rendertargets +// `buffer` and `buffer_parameters` members typedef struct { - i32 num_attached_buffers; - ivec3 dimensions; // All objects attached to a framebuffer (in OpenGL) must have same size + // Number of attached textures + i8 num_textures; + // Number of attached renderbuffers + i8 num_renderbuffers; + // All objects attached to a framebuffer (at least in OpenGL) must have same + // size. Set the remainding dimensions to zero to indicate they're unused + // even though, mathematically speaking, they should be one. + ivec3 dimensions; } FramebufferParameters; -// A render target takes a bunch of drawcalls, and renders it to a texture. +// A render target takes a bunch of drawcalls, and renders it to either a +// texture or buffer. // TODO: user runs "init" for their rendertarget(s) "stack", possibly using some -// predefined macro "DEFAULT_RENDERTARGETS". Requires user to specify number of lights et. al. +// predefined macro "DEFAULT_RENDERTARGETS". Requires user to specify number of +// lights et. al. +// The RenderTargets is technically two SOAs: +// * framebuffers, holding the OpenGL "framebuffer name", buffer parameters, +// camera, and resize callbacks, +// * and "buffers" (generalized name for "textures" and "renderbuffers") typedef struct { - // glFrameBuffer + // Number of framebuffers. usize framebuffer_len; + // OpenGL "names" u32 *framebuffer; // Number of buffers attached to each of the framebuffers. Used to iteratively @@ -294,22 +307,25 @@ typedef struct { // One cam per framebuffer, is usually a pointer to user-allocated camera Camera **cam; - //// Called when window is resized with new width and height. Set to NULL to - //// skip changing texture_size. Comparable to glViewport. - //// This function can be heavy due to it destroying and re-creating framebuffers. - //// Which requires me to store the parameters that they we're created with. - //void (**framebuffer_size_callback)(ivec2*,ivec2); + // Indirectly called when window is resized with new width and height. Set to + // NULL to skip changing framebuffer_size. Comparable to glViewport. + // This function can be heavy due to it destroying and re-creating buffers, + // textures and framebuffers. + void (**framebuffer_size_callback)(ivec3* dst,ivec2 src); - //// Called when window is resized. Calls the respective texture_size_callback function at - //// the same index if not null. The camera resize callback function is then - //// called with the new dimensions of the texture. - //// Set to NULL to skip changing the camera size/perspective. - void (**camera_reset_callback)(Camera*,ivec2); + // Called when window is resized. Calls the respective framebuffer_size_callback function at + // the same index if not null. The camera resize callback function is then + // called with the new dimensions of the framebuffer if + // framebuffer_size_callback is not null, otherwise called with + // the new window size. + // Set to NULL to skip changing the camera size/perspective. + void (**camera_reset_callback)(Camera*,ivec2 src); - // glTexture / glRenderBuffer / glBuffer / glWhatever. + // glTexture and glRenderBuffer // Currently, each buffer must be either a texture or a (depth and/or stencil) // buffer. usize buffer_len; + // OpenGL buffer names u32 *buffer; // Stores per-buffer type, and type-specific parameters. u32 *buffer_parameters; @@ -362,6 +378,9 @@ ShaderType guess_shadertype_from_filename(const char *restrict fname); Texture createTextureFromImageData(unsigned char* image_data, i32 width, i32 height, u8 components); +// Creates and initializes buffers for the framebuffer +void r_setup_framebuffer(void *restrict ctx, u32 framebuffer_id, FramebufferParameters param, u32 *restrict buffer_array, u32 *restrict buffer_parameters); + void r_create_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, usize num_targets); void r_destroy_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, usize num_targets); void r_create_textures(void *restrict ctx, u32* restrict texture_array, u32* restrict texture_types, ivec3* restrict texture_sizes, usize num_targets); diff --git a/src/rendering.c b/src/rendering.c index 0643c70..8c3846d 100644 --- a/src/rendering.c +++ b/src/rendering.c @@ -4,6 +4,7 @@ #include <GLFW/glfw3.h> #include <cglm/cam.h> #include <cglm/vec2.h> +#include <cglm/ivec3.h> #include <cglm/mat4.h> @@ -707,6 +708,24 @@ void r_init_renderstack( window_init_renderstack(GLOBAL_PLATFORM->window, num_fbuf, num_buf, fb_params, buffer_params); } +void r_setup_framebuffer(void *restrict ctx, u32 framebuffer_id, FramebufferParameters param, u32 *restrict buffer_array, u32 *restrict buffer_parameters) { + r_create_textures(ctx, buffer_array, + buffer_parameters, + ¶m.dimensions, + param.num_textures); + + r_create_renderbuffers(ctx, &buffer_array[param.num_textures], + &buffer_parameters[param.num_textures], + ¶m.dimensions, + param.num_renderbuffers); + + r_attach_buffers(ctx, + framebuffer_id, + buffer_array, + buffer_parameters, + param.num_textures + param.num_renderbuffers); +} + void r_create_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, usize num_targets) { const GladGLContext* gl = (GladGLContext*)ctx; @@ -764,7 +783,7 @@ void r_create_textures(void* restrict ctx, u32* restrict texture_array, gl->CreateTextures(GL_TEXTURE_1D, num_targets, texture_array); ASSERT(!gl->GetError()); for (usize i = 0; i < num_targets; i++) { - gl->TextureStorage1D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_FMT_GET(texture_parameters[i])), texture_sz[0]); + gl->TextureStorage1D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_GET_PARAMETER(texture_parameters[i])), texture_sz[0]); } break; @@ -772,7 +791,7 @@ void r_create_textures(void* restrict ctx, u32* restrict texture_array, gl->CreateTextures(GL_TEXTURE_2D, num_targets, texture_array); ASSERT(!gl->GetError()); for (usize i = 0; i < num_targets; i++) { - gl->TextureStorage2D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_FMT_GET(texture_parameters[i])), texture_sz[0], texture_sz[1]); + gl->TextureStorage2D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_GET_PARAMETER(texture_parameters[i])), texture_sz[0], texture_sz[1]); } break; @@ -780,7 +799,7 @@ void r_create_textures(void* restrict ctx, u32* restrict texture_array, gl->CreateTextures(GL_TEXTURE_3D, num_targets, texture_array); ASSERT(!gl->GetError()); for (usize i = 0; i < num_targets; i++) { - gl->TextureStorage3D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_FMT_GET(texture_parameters[i])), texture_sz[0], texture_sz[1], texture_sz[2]); + gl->TextureStorage3D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_GET_PARAMETER(texture_parameters[i])), texture_sz[0], texture_sz[1], texture_sz[2]); } break; @@ -834,7 +853,7 @@ void r_create_renderbuffers(void *restrict ctx, u32* restrict buffer_array, u32* for (usize i = 0; i < num_buffers; i++) { gl->NamedRenderbufferStorage( buffer_array[i], - gl_texture_format(BUFFERPARAMETER_FMT_GET(buffer_types[i])), + gl_texture_format(BUFFERPARAMETER_GET_PARAMETER(buffer_types[i])), buffer_sizes[i][0], buffer_sizes[i][1] ); 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; } |
