summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/daw.c14
-rw-r--r--src/include/daw/rendering.h77
-rw-r--r--src/rendering.c110
-rw-r--r--src/window.c36
4 files changed, 185 insertions, 52 deletions
diff --git a/src/daw.c b/src/daw.c
index 2687f11..4a99d33 100644
--- a/src/daw.c
+++ b/src/daw.c
@@ -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]);