From 5bc2fd2c59384c16a80435dc236567a5b4f83cd7 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Mon, 7 Feb 2022 08:59:10 -0500 Subject: [PATCH] change the way we store the LightsBuffer data to better fit openGL previously, we trying to store the 'header' for LightsBuffer as flat data types in cpp. This gave an incorrect offset because the pointers for the array data were also included in the 'buffer'. Now we've got a new pointer, 'buffer', and all the fields in the header are pointers into the buffer address space, so we can align everything properly --- src/tangerine.cpp | 30 +++++++++++++++++++++--------- src/tangerine.h | 22 ++++++++++------------ 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/tangerine.cpp b/src/tangerine.cpp index 6fa33b8..5ed870f 100644 --- a/src/tangerine.cpp +++ b/src/tangerine.cpp @@ -314,19 +314,31 @@ initLights(MemoryArena* arena, GLContext* gl_ctx, u32 max_lights) // FIXME: revisit for 'Scene' abstraction // TODO: we need a way to do this automatically somehow - u32 buf_size = 8 * sizeof(u32) // NOTE: 'header' + LightsBuffer* lb = ARENA_ALLOC(arena, LightsBuffer, 1); + lb->buf_size = 8 * sizeof(u32) // NOTE: 'header' + 6 * max_lights * sizeof(glm::vec4); // NOTE: vector arrays + LOGF(Debug, "buf_size: %d\n", lb->buf_size); + lb->buffer = ARENA_ALLOC(arena, u8, lb->buf_size); - LOGF(Debug, "buf_size: %d\n", buf_size); + lb->max_p_lights = (u32*) lb->buffer; + lb->active_p_lights = + (u32*) arenaGetAddressOffset(lb->max_p_lights, sizeof(u32)); + lb->max_d_lights = + (u32*) arenaGetAddressOffset(lb->active_p_lights, sizeof(u32)); + lb->active_d_lights = + (u32*) arenaGetAddressOffset(lb->max_d_lights, sizeof(u32)); - LightsBuffer* lb = (LightsBuffer*) ARENA_ALLOC(arena, u8, buf_size); - lb->buf_size = buf_size; - lb->max_p_lights = max_lights; - lb->max_d_lights = max_lights; + *lb->max_p_lights = max_lights; + *lb->max_d_lights = max_lights; + + // NOTE: add padding, we're not actually using this since 4 * u32 is on a + // 16 byte boundary, but will be helpful if we need to add more 'headers' + // in the future + void* arr_start = arenaGetAddressOffset(lb->buffer, 8 * sizeof(u32)); // NOTE: set offsets for array pointers - lb->pl_positions = (glm::vec4*) arenaGetAddressOffset(lb, sizeof(*lb)); u32 arr_size = max_lights * sizeof(glm::vec4); + lb->pl_positions = (glm::vec4*) arr_start; lb->pl_colors = (glm::vec4*) arenaGetAddressOffset(lb->pl_positions, arr_size); lb->pl_intensities = @@ -350,8 +362,8 @@ initLights(MemoryArena* arena, GLContext* gl_ctx, u32 max_lights) glGenBuffers(1, &lights_ubo->id); glBindBuffer(lights_ubo->target, lights_ubo->id); glBufferData(lights_ubo->target, - buf_size, - lb, + lb->buf_size, + lb->buffer, GL_DYNAMIC_DRAW); glBindBufferBase(lights_ubo->target, lights_ubo->binding_idx, diff --git a/src/tangerine.h b/src/tangerine.h index e7e1ee8..4a202fd 100644 --- a/src/tangerine.h +++ b/src/tangerine.h @@ -107,16 +107,17 @@ struct GLClearColor }; // NOTE: structure to match the layout of the 'lights' uniform in a shader +// all the pointers are pointers into the address space of 'buffer'. the vec4 +// pointers are required to start on 16 byte boundaries as per layout std140, +// so there may be some padding added between the 'header', and the start of +// the arrays struct LightsBuffer { u32 buf_size; - u32 max_p_lights; - u32 active_p_lights; - u32 max_d_lights; - u32 active_d_lights; - - // NOTE: padding for std140, vec4 need to be aligned at 16 bytes - u8 padding[12]; + u32* max_p_lights; + u32* active_p_lights; + u32* max_d_lights; + u32* active_d_lights; glm::vec4* pl_positions; glm::vec4* pl_colors; @@ -125,6 +126,8 @@ struct LightsBuffer glm::vec4* dl_directions; glm::vec4* dl_colors; glm::uvec4* dl_intensities; + + void* buffer; }; struct RenderState @@ -146,11 +149,6 @@ struct RenderState // could match up with gltf scene graph where everyting is part of a node // TODO: will also need other types of lights: directional, spotlight LightsBuffer* lights_buf; -#if 0 - u32 num_lights; - u32 max_lights; - PointLight* lights; -#endif };