diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/daw.c | 14 | ||||
| -rw-r--r-- | src/include/daw/rendering.h | 77 | ||||
| -rw-r--r-- | src/rendering.c | 110 | ||||
| -rw-r--r-- | src/window.c | 36 |
4 files changed, 185 insertions, 52 deletions
@@ -245,13 +245,21 @@ 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. + ivec2 wsz; + window_get_size(&wsz); FramebufferParameters p[] = { - {.num_attached_buffers = 1, {1600,1600}}, + {.num_attached_buffers = 2, .dimensions = {wsz[0], wsz[1], 0}}, }; u32 t[] = { - BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_TEXTURE_2D | BUFFERPARAMETER_TEXTURE_FMT_RGBA8) + BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_TEXTURE_2D | BUFFERPARAMETER_FMT_RGBA8), + // The depth buffer could also be a texture like so: + // BUFFERPARAMETER_SET_PARAMETER( + // BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), + // BUFFERPARAMETER_TEXTURE_2D | BUFFERPARAMETER_FMT_DEPTH + // ), + BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_render), BUFFERPARAMETER_RENDERBUFFER_DEPTH | BUFFERPARAMETER_FMT_DEPTH), }; - window_init_renderstack(w, 1, 1, p, t); + window_init_renderstack(w, 1, 2, p, t); //w->render_targets->cam[0] = &default_renderbuffer_camera; } diff --git a/src/include/daw/rendering.h b/src/include/daw/rendering.h index ecfb438..9f8ba7c 100644 --- a/src/include/daw/rendering.h +++ b/src/include/daw/rendering.h @@ -206,26 +206,7 @@ typedef enum { } BufferType; -// Buffer parameter: Frame buffer -// Buffer parameter: Texture buffer -#define BUFFERPARAMETER_TEXTURE_GET_DIMENSION(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & ((1 << 3) - 1)) -#define BUFFERPARAMETER_TEXTURE_1D 1 -#define BUFFERPARAMETER_TEXTURE_2D 2 -#define BUFFERPARAMETER_TEXTURE_3D 3 -#define BUFFERPARAMETER_TEXTURE_4D 4 - -// TODO: Change `2` once we add support for more formats -#define BUFFERPARAMETER_TEXTURE_GET_FORMAT(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & (((1 << 2) - 1) << 3)) -#define BUFFERPARAMETER_TEXTURE_FMT_RGBA8 (1 << 4) -#define BUFFERPARAMETER_TEXTURE_FMT_SRGB8 (2 << 4) -#define BUFFERPARAMETER_TEXTURE_FMT_SRGBA8 (3 << 4) - -//TODO: texture formats - -// Buffer parameter: Buffer buffer -#define BUFFERPARAMETER_BUFFER_DEPTH 1 -#define BUFFERPARAMETER_BUFFER_STENCIL 2 - +/* Buffer set/get macros */ // `buffer_definition` has the first 4 bits for the type, #define BUFFERPARAMETER_MASK_TYPE ((1 << 4) - 1) // next 16 bits for the type-specific parameters @@ -236,12 +217,58 @@ typedef enum { #define BUFFERPARAMETER_GET_PARAMETER(bufferparam) \ ((bufferparam & BUFFERPARAMETER_MASK_PARAMETER) >> 4) -// SET operations clear the masked bits that you're setting +// SET operations clear the masked bits that you're setting. Set multiple parameters by +// OR'ing them. #define BUFFERPARAMETER_SET_TYPE(bufferparam, type) \ (BufferType)((bufferparam & ~BUFFERPARAMETER_MASK_TYPE) | type) #define BUFFERPARAMETER_SET_PARAMETER(bufferparam, param) \ ((bufferparam & ~BUFFERPARAMETER_MASK_PARAMETER) | ((param) << 4)) +// Textures and RenderBuffers can have different formats internally. These are +// mutually exclusive and shared between texture and renderbuffer buffers. + +//TODO: More formats +#define BUFFERPARAMETER_FMT_RGBA8 (1 << 8) +#define BUFFERPARAMETER_FMT_SRGB8 (2 << 8) +#define BUFFERPARAMETER_FMT_SRGBA8 (3 << 8) + +#define BUFFERPARAMETER_FMT_DEPTH24_STENCIL8 (4 << 8) +#define BUFFERPARAMETER_FMT_DEPTH16 (5 << 8) +#define BUFFERPARAMETER_FMT_DEPTH24 (6 << 8) +#define BUFFERPARAMETER_FMT_DEPTH32 (7 << 8) +#define BUFFERPARAMETER_FMT_DEPTH32F (8 << 8) +#define BUFFERPARAMETER_FMT_STENCIL8 (9 << 8) + +// "Easy default" values +#define BUFFERPARAMETER_FMT_DEPTH_STENCIL BUFFERPARAMETER_FMT_DEPTH24_STENCIL8 +#define BUFFERPARAMETER_FMT_DEPTH BUFFERPARAMETER_FMT_DEPTH16 +#define BUFFERPARAMETER_FMT_STENCIL BUFFERPARAMETER_FMT_STENCIL8 + +// TODO: Merge Texture & RenderBuffer masks & getters/setters. They're basically +// identical, and we differentiate between them anyways wrt. dimensions, depth, +// stencil, and depth+stencil. + +// Buffer parameter: Frame buffer +// Buffer parameter: Texture buffer +#define BUFFERPARAMETER_TEXTURE_GET_DIMENSION(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & ((1 << 4) - 1)) +#define BUFFERPARAMETER_TEXTURE_1D 1 +#define BUFFERPARAMETER_TEXTURE_2D 2 +#define BUFFERPARAMETER_TEXTURE_3D 3 +#define BUFFERPARAMETER_TEXTURE_4D 4 + +// TODO: Change `2` once we add support for more formats +#define BUFFERPARAMETER_TEXTURE_GET_FORMAT(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & (((1 << 8) - 1) << 4)) + +// Buffer parameter: Buffer buffer +// A buffer can be either a depth and/or stencil buffer. Custom buffers could be +// implemented for this at some point. +// It is important that the types here are bitwise non-overlapping. +#define BUFFERPARAMETER_RENDERBUFFER_GET_TYPE(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & ((1 << 4) - 1)) +#define BUFFERPARAMETER_RENDERBUFFER_DEPTH 1 +#define BUFFERPARAMETER_RENDERBUFFER_STENCIL 2 + +#define BUFFERPARAMETER_RENDERBUFFER_GET_FORMAT(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & (((1 << 8) - 1)) << 4) + typedef struct { i32 num_attached_buffers; ivec3 dimensions; // All objects attached to a framebuffer (in OpenGL) must have same size @@ -276,7 +303,9 @@ typedef struct { //// Set to NULL to skip changing the camera size/perspective. void (**camera_reset_callback)(Camera*,ivec2); - // glTexture / glRenderBuffer / glBuffer / glWhatever + // glTexture / glRenderBuffer / glBuffer / glWhatever. + // Currently, each buffer must be either a texture or a (depth and/or stencil) + // buffer. usize buffer_len; u32 *buffer; // Stores per-buffer type, and type-specific parameters. @@ -334,6 +363,10 @@ void r_create_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, 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); void r_destroy_textures(void *restrict ctx, u32* textures, usize num_textures); +void r_create_renderbuffers(void *restrict ctx, u32* restrict buffer_array, u32* restrict buffer_types, ivec3* restrict buffer_sizes, usize num_buffers); +void r_destroy_renderbuffers(void *restrict ctx, u32* buffers, usize num_buffers); + +// Attaches `num_buffers` to the framebuffer. void r_attach_buffers(void *restrict ctx, u32 fbo, u32* buffers, u32* buffer_parameters, i32 num_buffers); void r_init_renderstack( diff --git a/src/rendering.c b/src/rendering.c index 88b1b9c..3faf91c 100644 --- a/src/rendering.c +++ b/src/rendering.c @@ -719,28 +719,35 @@ void r_destroy_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, gl->DeleteFramebuffers(num_targets, framebuffer_array); } +static u32 gl_texture_format(u32 texture_format) { + switch (texture_format) { + case BUFFERPARAMETER_FMT_RGBA8: return GL_RGBA8; + case BUFFERPARAMETER_FMT_SRGB8: return GL_SRGB; + case BUFFERPARAMETER_FMT_SRGBA8: return GL_SRGB8_ALPHA8; + + case BUFFERPARAMETER_FMT_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8; + case BUFFERPARAMETER_FMT_DEPTH16: return GL_DEPTH_COMPONENT16; + case BUFFERPARAMETER_FMT_DEPTH24: return GL_DEPTH_COMPONENT24; + case BUFFERPARAMETER_FMT_DEPTH32: return GL_DEPTH_COMPONENT32; + case BUFFERPARAMETER_FMT_DEPTH32F: return GL_DEPTH_COMPONENT32F; + case BUFFERPARAMETER_FMT_STENCIL8: return GL_STENCIL_INDEX8; + + default: + ERROR("Failed to convert format to GL internal format!"); + exit(EXIT_FAILURE); + } +} + void r_create_textures(void* restrict ctx, u32* restrict texture_array, u32* restrict texture_parameters, ivec3* restrict texture_size, usize num_targets) { const GladGLContext* gl = (GladGLContext*)ctx; u32 texture_dim = BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[0]); - u32 texture_format = BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[0]); - u32 gl_texture_format; u32 err; for (usize i = 1; i < num_targets; i++) { ASSERT(texture_dim == BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[i])); - ASSERT(texture_format == BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])); - } - - switch (texture_format) { - case BUFFERPARAMETER_TEXTURE_FMT_RGBA8: gl_texture_format = GL_RGBA8; break; - case BUFFERPARAMETER_TEXTURE_FMT_SRGB8: gl_texture_format = GL_SRGB; break; - case BUFFERPARAMETER_TEXTURE_FMT_SRGBA8: gl_texture_format = GL_SRGB8_ALPHA8; break; - default: - ERROR("Failed to convert format to GL internal format!"); - exit(EXIT_FAILURE); } // Convert the texturetype to GL texturetype @@ -749,7 +756,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, (*texture_size)[0]); + gl->TextureStorage1D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])), (*texture_size)[0]); } break; @@ -757,7 +764,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, (*texture_size)[0], (*texture_size)[1]); + gl->TextureStorage2D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])), (*texture_size)[0], (*texture_size)[1]); } break; @@ -765,7 +772,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, (*texture_size)[0], (*texture_size)[1], (*texture_size)[2]); + gl->TextureStorage3D(texture_array[i], 1, gl_texture_format(BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])), (*texture_size)[0], (*texture_size)[1], (*texture_size)[2]); } break; @@ -814,18 +821,79 @@ void r_destroy_textures(void *restrict ctx, u32* textures, usize num_textures) { gl->DeleteTextures(num_textures, textures); } +// I know there's a "size too many", but it is included for easier +// interopability with r_create_textures +void r_create_renderbuffers(void *restrict ctx, u32* restrict buffer_array, u32* restrict buffer_types, ivec3* restrict buffer_sizes, usize num_buffers) { + GladGLContext *restrict gl = (GladGLContext*)ctx; + + gl->CreateRenderbuffers(num_buffers, buffer_array); + for (usize i = 0; i < num_buffers; i++) { + gl->NamedRenderbufferStorage( + buffer_array[i], + gl_texture_format(BUFFERPARAMETER_RENDERBUFFER_GET_FORMAT(buffer_types[i])), + buffer_sizes[i][0], + buffer_sizes[i][1] + ); + } + +} + +void r_destroy_renderbuffers(void *restrict ctx, u32* buffers, usize num_buffers) { + ((GladGLContext *restrict)ctx)->DeleteRenderbuffers(num_buffers, buffers); +} + +static u32 gl_renderbuffer_type(u32 buffer_param) { + switch (BUFFERPARAMETER_RENDERBUFFER_GET_TYPE(buffer_param)) { + case BUFFERPARAMETER_RENDERBUFFER_DEPTH: + return GL_DEPTH_ATTACHMENT; + case BUFFERPARAMETER_RENDERBUFFER_STENCIL: + return GL_STENCIL_ATTACHMENT; + case (BUFFERPARAMETER_RENDERBUFFER_DEPTH | BUFFERPARAMETER_RENDERBUFFER_STENCIL): + return GL_DEPTH_STENCIL_ATTACHMENT; + default: + UNIMPLEMENTED; + } + return -1; +} + void r_attach_buffers(void *restrict ctx, u32 fbo, u32* buffers, u32* buffer_parameters, i32 num_buffers) { const GladGLContext *restrict gl = (GladGLContext*)ctx; + DEBUG("Attaching to FBO %d\n", fbo); + u32 err; for (i32 i = 0; i < num_buffers; i++) { - BufferType t = BUFFERPARAMETER_GET_TYPE(buffer_parameters[i]); - - if (t != BufferType_texture) UNIMPLEMENTED; - - // TODO: FINISH ME - gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, buffers[i], 0); + switch (BUFFERPARAMETER_GET_TYPE(buffer_parameters[i])) { + case BufferType_frame: + UNIMPLEMENTED; + case BufferType_texture: + switch (BUFFERPARAMETER_TEXTURE_GET_FORMAT(buffer_parameters[i])) { + case BUFFERPARAMETER_FMT_DEPTH24_STENCIL8: + gl->NamedFramebufferTexture(fbo, GL_DEPTH_STENCIL_ATTACHMENT, buffers[i], 0); + break; + case BUFFERPARAMETER_FMT_DEPTH16: + case BUFFERPARAMETER_FMT_DEPTH24: + case BUFFERPARAMETER_FMT_DEPTH32: + case BUFFERPARAMETER_FMT_DEPTH32F: + gl->NamedFramebufferTexture(fbo, GL_DEPTH_ATTACHMENT, buffers[i], 0); + break; + case BUFFERPARAMETER_FMT_STENCIL8: + gl->NamedFramebufferTexture(fbo, GL_STENCIL_ATTACHMENT, buffers[i], 0); + break; + default: + gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, buffers[i], 0); + break; + } + break; + case BufferType_render: + gl->NamedFramebufferRenderbuffer(fbo, gl_renderbuffer_type(buffer_parameters[i]), GL_RENDERBUFFER, buffers[i]); + break; + case BufferType_buffer: + UNIMPLEMENTED; + default: + UNIMPLEMENTED; + } err = gl->GetError(); if (err) { diff --git a/src/window.c b/src/window.c index 7e7bfb2..36c1612 100644 --- a/src/window.c +++ b/src/window.c @@ -166,19 +166,43 @@ void window_init_renderstack(Window *restrict w, // Iteratively set up each framebuffer and framebuffer-attached objects usize buffer_offset = 0; for (usize fb_idx = 0; fb_idx < num_fbuf; fb_idx++) { - FramebufferParameters *p = &t->framebuffer_parameters[fb_idx]; - // Check everything is a texture, cuz rn. we don't support anything else - for (isize buffer_idx = 0; buffer_idx < p->num_attached_buffers; buffer_idx++) { - ASSERT(BUFFERPARAMETER_GET_TYPE(t->buffer_parameters[buffer_offset + buffer_idx]) == BufferType_texture); + + // 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, - t->framebuffer_parameters[fb_idx].num_attached_buffers); + 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], &t->buffer[buffer_offset], &t->buffer_parameters[buffer_offset], t->framebuffer_parameters[fb_idx].num_attached_buffers); + r_attach_buffers(w->context, + t->framebuffer[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]); |
