From bb314cfa31fdf928fb8bbc74c28c3cc173ecd557 Mon Sep 17 00:00:00 2001 From: W2Wizard <63303990+W2Wizard@users.noreply.github.com> Date: Sat, 20 Aug 2022 21:11:22 +0200 Subject: [PATCH 1/5] Initial attempt at fixing depth issues Co-Authored-By: VNC <52937757+VNNCC@users.noreply.github.com> --- include/MLX42/MLX42.h | 22 ++------ include/MLX42/MLX42_Int.h | 10 +++- src/font/mlx_font.c | 2 +- src/mlx_images.c | 115 ++++++++++++++++++-------------------- src/mlx_loop.c | 12 ++-- src/mlx_window.c | 21 ++++++- src/utils/mlx_list.c | 61 -------------------- 7 files changed, 91 insertions(+), 152 deletions(-) diff --git a/include/MLX42/MLX42.h b/include/MLX42/MLX42.h index 867189f..d7dc3c6 100644 --- a/include/MLX42/MLX42.h +++ b/include/MLX42/MLX42.h @@ -73,15 +73,15 @@ typedef struct xpm * * @param x The x location. * @param y The y location. - * @param z The z depth, controls if the image is on the fore or background. + * @param custom_depth The custom z depth, controls if the image is on the fore or background. * @param enabled If true, the instance is drawn else its not. */ typedef struct mlx_instance { - int32_t x; - int32_t y; - int32_t z; - bool enabled; + int32_t x; + int32_t y; + int32_t custom_depth; + bool enabled; } mlx_instance_t; /** @@ -678,18 +678,6 @@ void mlx_delete_image(mlx_t* mlx, mlx_image_t* image); */ bool mlx_resize_image(mlx_image_t* img, uint32_t nwidth, uint32_t nheight); -/** - * Sets the depth / Z axis value of an instance. - * - * NOTE: Keep in mind that images that are on the same Z layer, cut each other off. - * so if you don't see your image anymore make sure its not conflicting by being on - * the same layer as another image. - * - * @param[in] instance The instane on which to change the depth. - * @param[in] zdepth The new depth value. - */ -void mlx_set_instance_depth(mlx_instance_t* instance, int32_t zdepth); - //= String Functions =// /** diff --git a/include/MLX42/MLX42_Int.h b/include/MLX42/MLX42_Int.h index 11b0a9a..05b030c 100644 --- a/include/MLX42/MLX42_Int.h +++ b/include/MLX42/MLX42_Int.h @@ -215,6 +215,7 @@ typedef struct mlx_image_ctx } mlx_image_ctx_t; //= Functions =// + /** * All sorts of internal functions shared in the library that * should not be accessible to the user! No touch! @@ -229,7 +230,6 @@ void mlx_lstclear(mlx_list_t** lst, void (*del)(void*)); void mlx_lstadd_back(mlx_list_t** lst, mlx_list_t* new); void mlx_lstadd_front(mlx_list_t** lst, mlx_list_t* new); mlx_list_t* mlx_lstremove(mlx_list_t** lst, void* value, bool (*comp)(void*, void*)); -void mlx_sort_renderqueue(mlx_list_t** lst); //= Misc functions =// @@ -245,13 +245,17 @@ bool mlx_freen(int32_t count, ...); //= OpenGL Functions =// void mlx_update_matrix(const mlx_t* mlx, int32_t width, int32_t height); -void mlx_draw_instance(mlx_ctx_t* mlx, mlx_image_t* img, mlx_instance_t* instance); +void mlx_draw_instance(mlx_ctx_t* mlx, mlx_image_t* img, mlx_instance_t* instance, int32_t instanceDepth); void mlx_flush_batch(mlx_ctx_t* mlx); -// Utils Functions =// +//= Utils Functions =// bool mlx_getline(char** out, size_t* out_size, FILE* file); uint32_t mlx_rgba_to_mono(uint32_t color); int32_t mlx_atoi_base(const char* str, int32_t base); uint64_t mlx_fnv_hash(char* str, size_t len); + +//= Image Helper Functions =// +int32_t mlx_image_calculate_max_depth(mlx_image_t *image); + #endif diff --git a/src/font/mlx_font.c b/src/font/mlx_font.c index 8c92b60..72475cc 100644 --- a/src/font/mlx_font.c +++ b/src/font/mlx_font.c @@ -52,7 +52,7 @@ int32_t mlx_get_texoffset(char c) { const bool _isprint = isprint(c); - // NOTE: Cheesy branchless operation :D + // NOTE(W2): Cheesy branchless operation :D // +2 To skip line separator in texture return (-1 * !_isprint + ((FONT_WIDTH + 2) * (c - 32)) * _isprint); } diff --git a/src/mlx_images.c b/src/mlx_images.c index 79cc726..f3a55e1 100644 --- a/src/mlx_images.c +++ b/src/mlx_images.c @@ -14,7 +14,7 @@ //= Private =// -void mlx_flush_batch(mlx_ctx_t* mlx) +void mlx_flush_batch(mlx_ctx_t *mlx) { if (mlx->batch_size <= 0) return; @@ -27,9 +27,9 @@ void mlx_flush_batch(mlx_ctx_t* mlx) memset(mlx->bound_textures, 0, sizeof(mlx->bound_textures)); } -static int8_t mlx_bind_texture(mlx_ctx_t* mlx, mlx_image_t* img) +static int8_t mlx_bind_texture(mlx_ctx_t *mlx, mlx_image_t *img) { - const GLint handle = (GLint)((mlx_image_ctx_t*)img->context)->texture; + const GLint handle = (GLint)((mlx_image_ctx_t *)img->context)->texture; // Attempt to bind the texture, or obtain the index if it is already bound. for (int8_t i = 0; i < 16; i++) @@ -60,22 +60,22 @@ static int8_t mlx_bind_texture(mlx_ctx_t* mlx, mlx_image_t* img) * Internal function to draw a single instance of an image * to the screen. */ -void mlx_draw_instance(mlx_ctx_t* mlx, mlx_image_t* img, mlx_instance_t* instance) +void mlx_draw_instance(mlx_ctx_t *mlx, mlx_image_t *img, mlx_instance_t *instance, int32_t instanceDepth) { - float w = (float) img->width; - float h = (float) img->height; - float x = (float) instance->x; - float y = (float) instance->y; - float z = (float) instance->z; + float w = (float)img->width; + float h = (float)img->height; + float x = (float)instance->x; + float y = (float)instance->y; + float z = (float)instanceDepth; int8_t tex = mlx_bind_texture(mlx, img); vertex_t vertices[6] = { - (vertex_t){x, y, z, 0.f, 0.f, tex}, - (vertex_t){x + w, y + h, z, 1.f, 1.f, tex}, - (vertex_t){x + w, y, z, 1.f, 0.f, tex}, - (vertex_t){x, y, z, 0.f, 0.f, tex}, - (vertex_t){x, y + h, z, 0.f, 1.f, tex}, - (vertex_t){x + w, y + h, z, 1.f, 1.f, tex}, + (vertex_t){x, y, z, 0.f, 0.f, tex}, + (vertex_t){x + w, y + h, z, 1.f, 1.f, tex}, + (vertex_t){x + w, y, z, 1.f, 0.f, tex}, + (vertex_t){x, y, z, 0.f, 0.f, tex}, + (vertex_t){x, y + h, z, 0.f, 1.f, tex}, + (vertex_t){x + w, y + h, z, 1.f, 1.f, tex}, }; memmove(mlx->batch_vertices + mlx->batch_size, vertices, sizeof(vertices)); mlx->batch_size += 6; @@ -84,9 +84,9 @@ void mlx_draw_instance(mlx_ctx_t* mlx, mlx_image_t* img, mlx_instance_t* instanc mlx_flush_batch(mlx); } -mlx_instance_t* mlx_grow_instances(mlx_image_t* img, bool* did_realloc) +mlx_instance_t *mlx_grow_instances(mlx_image_t *img, bool *did_realloc) { - mlx_image_ctx_t* const ctx = img->context; + mlx_image_ctx_t *const ctx = img->context; if (img->count >= ctx->instances_capacity) { if (ctx->instances_capacity == 0) @@ -102,23 +102,7 @@ mlx_instance_t* mlx_grow_instances(mlx_image_t* img, bool* did_realloc) //= Public =// -void mlx_set_instance_depth(mlx_instance_t* instance, int32_t zdepth) -{ - MLX_NONNULL(instance); - - if (instance->z == zdepth) - return; - instance->z = zdepth; - - /** - * NOTE: The reason why we don't sort directly is that - * the user might call this function multiple times in a row and we don't - * want to sort for every change. Pre-loop wise that is. - */ - sort_queue = true; -} - -int32_t mlx_image_to_window(mlx_t* mlx, mlx_image_t* img, int32_t x, int32_t y) +int32_t mlx_image_to_window(mlx_t *mlx, mlx_image_t *img, int32_t x, int32_t y) { MLX_NONNULL(mlx); MLX_NONNULL(img); @@ -126,8 +110,8 @@ int32_t mlx_image_to_window(mlx_t* mlx, mlx_image_t* img, int32_t x, int32_t y) // Allocate buffers... img->count++; bool did_realloc; - mlx_instance_t* instances = mlx_grow_instances(img, &did_realloc); - draw_queue_t* queue = calloc(1, sizeof(draw_queue_t)); + mlx_instance_t *instances = mlx_grow_instances(img, &did_realloc); + draw_queue_t *queue = calloc(1, sizeof(draw_queue_t)); if (!instances || !queue) { if (did_realloc) @@ -138,36 +122,33 @@ int32_t mlx_image_to_window(mlx_t* mlx, mlx_image_t* img, int32_t x, int32_t y) // Set data... queue->image = img; int32_t index = queue->instanceid = img->count - 1; + img->instances = instances; img->instances[index].x = x; img->instances[index].y = y; - - // NOTE: We keep updating the Z for the convenience of the user. - // Always update Z depth to prevent overlapping images by default. - img->instances[index].z = ((mlx_ctx_t*)mlx->context)->zdepth++; + img->instances[index].custom_depth = -1; img->instances[index].enabled = true; // Add draw call... - sort_queue = true; - mlx_list_t* templst; + mlx_list_t *templst; if ((templst = mlx_lstnew(queue))) { - mlx_lstadd_front(&((mlx_ctx_t*)mlx->context)->render_queue, templst); + mlx_lstadd_back(&((mlx_ctx_t *)mlx->context)->render_queue, templst); return (index); } return (mlx_freen(2, instances, queue), mlx_error(MLX_MEMFAIL), -1); } -mlx_image_t* mlx_new_image(mlx_t* mlx, uint32_t width, uint32_t height) +mlx_image_t *mlx_new_image(mlx_t *mlx, uint32_t width, uint32_t height) { MLX_NONNULL(mlx); if (!width || !height || width > INT16_MAX || height > INT16_MAX) - return ((void*)mlx_error(MLX_INVDIM)); + return ((void *)mlx_error(MLX_INVDIM)); - const mlx_ctx_t* mlxctx = mlx->context; - mlx_image_t* newimg = calloc(1, sizeof(mlx_image_t)); - mlx_image_ctx_t* newctx = calloc(1, sizeof(mlx_image_ctx_t)); + const mlx_ctx_t *mlxctx = mlx->context; + mlx_image_t *newimg = calloc(1, sizeof(mlx_image_t)); + mlx_image_ctx_t *newctx = calloc(1, sizeof(mlx_image_ctx_t)); if (!newimg || !newctx) { mlx_freen(2, newimg, newctx); @@ -175,15 +156,15 @@ mlx_image_t* mlx_new_image(mlx_t* mlx, uint32_t width, uint32_t height) } newimg->enabled = true; newimg->context = newctx; - (*(uint32_t*)&newimg->width) = width; - (*(uint32_t*)&newimg->height) = height; + (*(uint32_t *)&newimg->width) = width; + (*(uint32_t *)&newimg->height) = height; if (!(newimg->pixels = calloc(width * height, sizeof(int32_t)))) { mlx_freen(2, newimg, newctx); return ((void *)mlx_error(MLX_MEMFAIL)); } - mlx_list_t* newentry; + mlx_list_t *newentry; if (!(newentry = mlx_lstnew(newimg))) { mlx_freen(3, newimg->pixels, newimg->context, newimg); @@ -197,31 +178,43 @@ mlx_image_t* mlx_new_image(mlx_t* mlx, uint32_t width, uint32_t height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - mlx_lstadd_front((mlx_list_t**)(&mlxctx->images), newentry); + mlx_lstadd_front((mlx_list_t **)(&mlxctx->images), newentry); return (newimg); } -void mlx_delete_image(mlx_t* mlx, mlx_image_t* image) +void mlx_delete_image(mlx_t *mlx, mlx_image_t *image) { MLX_NONNULL(mlx); MLX_NONNULL(image); - mlx_ctx_t* mlxctx = mlx->context; + mlx_ctx_t *mlxctx = mlx->context; // Delete all instances in the render queue - mlx_list_t* quelst; + mlx_list_t *quelst; while ((quelst = mlx_lstremove(&mlxctx->render_queue, image, &mlx_equal_inst))) mlx_freen(2, quelst->content, quelst); - mlx_list_t* imglst; + mlx_list_t *imglst; if ((imglst = mlx_lstremove(&mlxctx->images, image, &mlx_equal_image))) { - glDeleteTextures(1, &((mlx_image_ctx_t*)image->context)->texture); + glDeleteTextures(1, &((mlx_image_ctx_t *)image->context)->texture); mlx_freen(5, image->pixels, image->instances, image->context, imglst, image); } } -bool mlx_resize_image(mlx_image_t* img, uint32_t nwidth, uint32_t nheight) +int32_t mlx_image_calculate_max_depth(mlx_image_t *image) +{ + int32_t depth = 0; + for (int32_t i = 0; i < image->count; i++) + { + const mlx_instance_t *instance = &image->instances[i]; + depth += instance->custom_depth > 0 ? instance->custom_depth : 1; + } + + return depth; +} + +bool mlx_resize_image(mlx_image_t *img, uint32_t nwidth, uint32_t nheight) { MLX_NONNULL(img); @@ -229,12 +222,12 @@ bool mlx_resize_image(mlx_image_t* img, uint32_t nwidth, uint32_t nheight) return (mlx_error(MLX_INVDIM)); if (nwidth != img->width || nheight != img->height) { - uint8_t* tempbuff = realloc(img->pixels, (nwidth * nheight) * BPP); + uint8_t *tempbuff = realloc(img->pixels, (nwidth * nheight) * BPP); if (!tempbuff) return (mlx_error(MLX_MEMFAIL)); img->pixels = tempbuff; - (*(uint32_t*)&img->width) = nwidth; - (*(uint32_t*)&img->height) = nheight; + (*(uint32_t *)&img->width) = nwidth; + (*(uint32_t *)&img->height) = nheight; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nwidth, nheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->pixels); } return (true); diff --git a/src/mlx_loop.c b/src/mlx_loop.c index cf0d531..6caade6 100644 --- a/src/mlx_loop.c +++ b/src/mlx_loop.c @@ -32,11 +32,7 @@ static void mlx_render_images(mlx_t* mlx) mlx_ctx_t* mlxctx = mlx->context; mlx_list_t* imglst = mlxctx->images; - if (sort_queue) - { - sort_queue = false; - mlx_sort_renderqueue(&mlxctx->render_queue); - } + // Sort queue! // Upload image textures to GPU while (imglst) @@ -50,14 +46,18 @@ static void mlx_render_images(mlx_t* mlx) } // Execute draw calls + int32_t depth = 0; mlx_list_t* render_queue = mlxctx->render_queue; while (render_queue) { draw_queue_t* drawcall = render_queue->content; mlx_instance_t* instance = &drawcall->image->instances[drawcall->instanceid]; + int32_t instanceDepth = instance->custom_depth > 0 ? instance->custom_depth : depth++; + if (drawcall && drawcall->image->enabled && instance->enabled) - mlx_draw_instance(mlx->context, drawcall->image, instance); + mlx_draw_instance(mlx->context, drawcall->image, instance, instanceDepth); + render_queue = render_queue->next; } } diff --git a/src/mlx_window.c b/src/mlx_window.c index 646edce..cc85b6e 100644 --- a/src/mlx_window.c +++ b/src/mlx_window.c @@ -21,7 +21,22 @@ void mlx_update_matrix(const mlx_t* mlx, int32_t width, int32_t height) { const mlx_ctx_t* mlxctx = mlx->context; - const float depth = mlxctx->zdepth; + const mlx_list_t* imglst = mlxctx->images; + + int32_t maxDepth = 1; + while (imglst) + { + mlx_image_t *image; + if (!(image = imglst->content)) + { + imglst = imglst->next; + continue; + } + + maxDepth += mlx_image_calculate_max_depth(image); + + imglst = imglst->next; + } /** * Incase the setting to stretch the image is set, we maintain the width and height but not @@ -33,9 +48,9 @@ void mlx_update_matrix(const mlx_t* mlx, int32_t width, int32_t height) const float matrix[16] = { 2.f / width, 0, 0, 0, 0, 2.f / -(height), 0, 0, - 0, 0, -2.f / (depth - -depth), 0, + 0, 0, -2.f / (maxDepth - -maxDepth), 0, -1, -(height / -height), - -((depth + -depth) / (depth - -depth)), 1 + -((maxDepth + -maxDepth) / (maxDepth - -maxDepth)), 1 }; glUniformMatrix4fv(glGetUniformLocation(mlxctx->shaderprogram, "ProjMatrix"), 1, GL_FALSE, matrix); diff --git a/src/utils/mlx_list.c b/src/utils/mlx_list.c index 99873e2..dc7e2fc 100644 --- a/src/utils/mlx_list.c +++ b/src/utils/mlx_list.c @@ -137,64 +137,3 @@ mlx_list_t* mlx_lstremove(mlx_list_t** lst, void* value, bool (*comp)(void*, voi lstcpy->prev->next = lstcpy->next; return (lstcpy); } - -// Retrieve Z value from queue. -static int32_t mlx_getdata(mlx_list_t* entry) -{ - const draw_queue_t* queue = entry->content; - - return (queue->image->instances[queue->instanceid].z); -} - -// Insert the entry back into head sorted. -static void mlx_insertsort(mlx_list_t** head, mlx_list_t* new) -{ - mlx_list_t* current; - - if (*head == NULL) - *head = new; - else if (mlx_getdata(*head) >= mlx_getdata(new)) - { - new->next = *head; - new->next->prev = new; - *head = new; - } - else - { - current = *head; - - // Find insertion location. - while (current->next != NULL && mlx_getdata(current->next) < mlx_getdata(new)) - current = current->next; - new->next = current->next; - - // Insert at the end - if (current->next != NULL) - new->next->prev = new; - current->next = new; - new->prev = current; - } -} - -/** - * Okay-ish sorting algorithm to sort the render queue / doubly linked list. - * We need to do this to fix transparency. - * - * @param lst The render queue. - */ -void mlx_sort_renderqueue(mlx_list_t** lst) -{ - mlx_list_t* sorted = NULL; - mlx_list_t* lstcpy = *lst; - - while (lstcpy != NULL) - { - mlx_list_t* next = lstcpy->next; - - // Separate entry out of list and insert it back but sorted. - lstcpy->prev = lstcpy->next = NULL; - mlx_insertsort(&sorted, lstcpy); - lstcpy = next; - } - *lst = sorted; -} From 796f9d32fe6d08cbbb60fd5ca72ee074baa0d0cb Mon Sep 17 00:00:00 2001 From: W2Wizard <63303990+W2Wizard@users.noreply.github.com> Date: Sat, 20 Aug 2022 21:13:36 +0200 Subject: [PATCH 2/5] FIx formatting Co-Authored-By: VNC <52937757+VNNCC@users.noreply.github.com> --- src/mlx_images.c | 60 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/mlx_images.c b/src/mlx_images.c index f3a55e1..64b53d5 100644 --- a/src/mlx_images.c +++ b/src/mlx_images.c @@ -14,7 +14,7 @@ //= Private =// -void mlx_flush_batch(mlx_ctx_t *mlx) +void mlx_flush_batch(mlx_ctx_t* mlx) { if (mlx->batch_size <= 0) return; @@ -27,9 +27,9 @@ void mlx_flush_batch(mlx_ctx_t *mlx) memset(mlx->bound_textures, 0, sizeof(mlx->bound_textures)); } -static int8_t mlx_bind_texture(mlx_ctx_t *mlx, mlx_image_t *img) +static int8_t mlx_bind_texture(mlx_ctx_t* mlx, mlx_image_t* img) { - const GLint handle = (GLint)((mlx_image_ctx_t *)img->context)->texture; + const GLint handle = (GLint)((mlx_image_ctx_t*)img->context)->texture; // Attempt to bind the texture, or obtain the index if it is already bound. for (int8_t i = 0; i < 16; i++) @@ -60,7 +60,7 @@ static int8_t mlx_bind_texture(mlx_ctx_t *mlx, mlx_image_t *img) * Internal function to draw a single instance of an image * to the screen. */ -void mlx_draw_instance(mlx_ctx_t *mlx, mlx_image_t *img, mlx_instance_t *instance, int32_t instanceDepth) +void mlx_draw_instance(mlx_ctx_t* mlx, mlx_image_t* img, mlx_instance_t* instance, int32_t instanceDepth) { float w = (float)img->width; float h = (float)img->height; @@ -84,9 +84,9 @@ void mlx_draw_instance(mlx_ctx_t *mlx, mlx_image_t *img, mlx_instance_t *instanc mlx_flush_batch(mlx); } -mlx_instance_t *mlx_grow_instances(mlx_image_t *img, bool *did_realloc) +mlx_instance_t* mlx_grow_instances(mlx_image_t* img, bool* did_realloc) { - mlx_image_ctx_t *const ctx = img->context; + mlx_image_ctx_t* const ctx = img->context; if (img->count >= ctx->instances_capacity) { if (ctx->instances_capacity == 0) @@ -102,7 +102,7 @@ mlx_instance_t *mlx_grow_instances(mlx_image_t *img, bool *did_realloc) //= Public =// -int32_t mlx_image_to_window(mlx_t *mlx, mlx_image_t *img, int32_t x, int32_t y) +int32_t mlx_image_to_window(mlx_t* mlx, mlx_image_t* img, int32_t x, int32_t y) { MLX_NONNULL(mlx); MLX_NONNULL(img); @@ -110,8 +110,8 @@ int32_t mlx_image_to_window(mlx_t *mlx, mlx_image_t *img, int32_t x, int32_t y) // Allocate buffers... img->count++; bool did_realloc; - mlx_instance_t *instances = mlx_grow_instances(img, &did_realloc); - draw_queue_t *queue = calloc(1, sizeof(draw_queue_t)); + mlx_instance_t* instances = mlx_grow_instances(img, &did_realloc); + draw_queue_t* queue = calloc(1, sizeof(draw_queue_t)); if (!instances || !queue) { if (did_realloc) @@ -130,7 +130,7 @@ int32_t mlx_image_to_window(mlx_t *mlx, mlx_image_t *img, int32_t x, int32_t y) img->instances[index].enabled = true; // Add draw call... - mlx_list_t *templst; + mlx_list_t* templst; if ((templst = mlx_lstnew(queue))) { mlx_lstadd_back(&((mlx_ctx_t *)mlx->context)->render_queue, templst); @@ -139,16 +139,16 @@ int32_t mlx_image_to_window(mlx_t *mlx, mlx_image_t *img, int32_t x, int32_t y) return (mlx_freen(2, instances, queue), mlx_error(MLX_MEMFAIL), -1); } -mlx_image_t *mlx_new_image(mlx_t *mlx, uint32_t width, uint32_t height) +mlx_image_t *mlx_new_image(mlx_t* mlx, uint32_t width, uint32_t height) { MLX_NONNULL(mlx); if (!width || !height || width > INT16_MAX || height > INT16_MAX) - return ((void *)mlx_error(MLX_INVDIM)); + return ((void*)mlx_error(MLX_INVDIM)); - const mlx_ctx_t *mlxctx = mlx->context; - mlx_image_t *newimg = calloc(1, sizeof(mlx_image_t)); - mlx_image_ctx_t *newctx = calloc(1, sizeof(mlx_image_ctx_t)); + const mlx_ctx_t* mlxctx = mlx->context; + mlx_image_t* newimg = calloc(1, sizeof(mlx_image_t)); + mlx_image_ctx_t* newctx = calloc(1, sizeof(mlx_image_ctx_t)); if (!newimg || !newctx) { mlx_freen(2, newimg, newctx); @@ -156,15 +156,15 @@ mlx_image_t *mlx_new_image(mlx_t *mlx, uint32_t width, uint32_t height) } newimg->enabled = true; newimg->context = newctx; - (*(uint32_t *)&newimg->width) = width; - (*(uint32_t *)&newimg->height) = height; + (*(uint32_t*)&newimg->width) = width; + (*(uint32_t*)&newimg->height) = height; if (!(newimg->pixels = calloc(width * height, sizeof(int32_t)))) { mlx_freen(2, newimg, newctx); return ((void *)mlx_error(MLX_MEMFAIL)); } - mlx_list_t *newentry; + mlx_list_t* newentry; if (!(newentry = mlx_lstnew(newimg))) { mlx_freen(3, newimg->pixels, newimg->context, newimg); @@ -178,43 +178,43 @@ mlx_image_t *mlx_new_image(mlx_t *mlx, uint32_t width, uint32_t height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - mlx_lstadd_front((mlx_list_t **)(&mlxctx->images), newentry); + mlx_lstadd_front((mlx_list_t**)(&mlxctx->images), newentry); return (newimg); } -void mlx_delete_image(mlx_t *mlx, mlx_image_t *image) +void mlx_delete_image(mlx_t* mlx, mlx_image_t* image) { MLX_NONNULL(mlx); MLX_NONNULL(image); - mlx_ctx_t *mlxctx = mlx->context; + mlx_ctx_t* mlxctx = mlx->context; // Delete all instances in the render queue - mlx_list_t *quelst; + mlx_list_t* quelst; while ((quelst = mlx_lstremove(&mlxctx->render_queue, image, &mlx_equal_inst))) mlx_freen(2, quelst->content, quelst); - mlx_list_t *imglst; + mlx_list_t* imglst; if ((imglst = mlx_lstremove(&mlxctx->images, image, &mlx_equal_image))) { - glDeleteTextures(1, &((mlx_image_ctx_t *)image->context)->texture); + glDeleteTextures(1, &((mlx_image_ctx_t*)image->context)->texture); mlx_freen(5, image->pixels, image->instances, image->context, imglst, image); } } -int32_t mlx_image_calculate_max_depth(mlx_image_t *image) +int32_t mlx_image_calculate_max_depth(mlx_image_t* image) { int32_t depth = 0; for (int32_t i = 0; i < image->count; i++) { - const mlx_instance_t *instance = &image->instances[i]; + const mlx_instance_t* instance = &image->instances[i]; depth += instance->custom_depth > 0 ? instance->custom_depth : 1; } return depth; } -bool mlx_resize_image(mlx_image_t *img, uint32_t nwidth, uint32_t nheight) +bool mlx_resize_image(mlx_image_t* img, uint32_t nwidth, uint32_t nheight) { MLX_NONNULL(img); @@ -222,12 +222,12 @@ bool mlx_resize_image(mlx_image_t *img, uint32_t nwidth, uint32_t nheight) return (mlx_error(MLX_INVDIM)); if (nwidth != img->width || nheight != img->height) { - uint8_t *tempbuff = realloc(img->pixels, (nwidth * nheight) * BPP); + uint8_t* tempbuff = realloc(img->pixels, (nwidth * nheight) * BPP); if (!tempbuff) return (mlx_error(MLX_MEMFAIL)); img->pixels = tempbuff; - (*(uint32_t *)&img->width) = nwidth; - (*(uint32_t *)&img->height) = nheight; + (*(uint32_t*)&img->width) = nwidth; + (*(uint32_t*)&img->height) = nheight; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nwidth, nheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->pixels); } return (true); From 7c9c3d29242671bb11786af62ae1c05ad54d98c2 Mon Sep 17 00:00:00 2001 From: W2Wizard <63303990+W2Wizard@users.noreply.github.com> Date: Sun, 21 Aug 2022 13:36:36 +0200 Subject: [PATCH 3/5] Implement vector Co-authored-by: VNC --- include/MLX42/MLX42_Int.h | 19 +++++++ src/mlx_images.c | 7 ++- src/utils/mlx_vec.c | 102 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 src/utils/mlx_vec.c diff --git a/include/MLX42/MLX42_Int.h b/include/MLX42/MLX42_Int.h index 05b030c..ea61470 100644 --- a/include/MLX42/MLX42_Int.h +++ b/include/MLX42/MLX42_Int.h @@ -94,6 +94,16 @@ typedef struct mlx_list struct mlx_list* prev; } mlx_list_t; +typedef struct mlx_vec +{ + void* data; + int32_t count; + + size_t capacity; + size_t elementSize; + int32_t position; +} mlx_vec_t; + //= Hook structs =// /** * There are 2 types of hooks, special and generics. @@ -186,6 +196,7 @@ typedef struct mlx_ctx mlx_list_t* hooks; mlx_list_t* images; mlx_list_t* render_queue; + int32_t instance_count; mlx_scroll_t scroll_hook; mlx_mouse_t mouse_hook; @@ -258,4 +269,12 @@ uint64_t mlx_fnv_hash(char* str, size_t len); //= Image Helper Functions =// int32_t mlx_image_calculate_max_depth(mlx_image_t *image); +//= Vector Functions =// + +void mlx_vector_init(mlx_vec_t* v, size_t elementSize); +void mlx_vector_push_back(mlx_vec_t* v, void* item); +void mlx_vector_set(mlx_vec_t* v, size_t index, void* item); +void* mlx_vector_get(mlx_vec_t* v, size_t index); +void mlx_vector_delete(mlx_vec_t* v, size_t index); +void mlx_vector_free(mlx_vec_t* v); #endif diff --git a/src/mlx_images.c b/src/mlx_images.c index 64b53d5..76e29df 100644 --- a/src/mlx_images.c +++ b/src/mlx_images.c @@ -107,6 +107,8 @@ int32_t mlx_image_to_window(mlx_t* mlx, mlx_image_t* img, int32_t x, int32_t y) MLX_NONNULL(mlx); MLX_NONNULL(img); + mlx_ctx_t* mlxctx = mlx->context; + // Allocate buffers... img->count++; bool did_realloc; @@ -133,7 +135,8 @@ int32_t mlx_image_to_window(mlx_t* mlx, mlx_image_t* img, int32_t x, int32_t y) mlx_list_t* templst; if ((templst = mlx_lstnew(queue))) { - mlx_lstadd_back(&((mlx_ctx_t *)mlx->context)->render_queue, templst); + mlx_lstadd_back(&(mlxctx->render_queue), templst); + mlxctx->instance_count++; return (index); } return (mlx_freen(2, instances, queue), mlx_error(MLX_MEMFAIL), -1); @@ -194,6 +197,8 @@ void mlx_delete_image(mlx_t* mlx, mlx_image_t* image) while ((quelst = mlx_lstremove(&mlxctx->render_queue, image, &mlx_equal_inst))) mlx_freen(2, quelst->content, quelst); + mlxctx->instance_count -= image->count; + mlx_list_t* imglst; if ((imglst = mlx_lstremove(&mlxctx->images, image, &mlx_equal_image))) { diff --git a/src/utils/mlx_vec.c b/src/utils/mlx_vec.c new file mode 100644 index 0000000..5cf3153 --- /dev/null +++ b/src/utils/mlx_vec.c @@ -0,0 +1,102 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* mlx_vec.c :+: :+: */ +/* +:+ */ +/* By: W2Wizard +#+ */ +/* +#+ */ +/* Created: 2022/08/20 21:33:52 by W2Wizard #+# #+# */ +/* Updated: 2022/08/20 21:33:52 by W2Wizard ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "MLX42/MLX42_Int.h" + +//= Private =// + +static void mlx_vector_resize(mlx_vec_t* v, int capacity) +{ + MLX_NONNULL(v); + + void **data = realloc(v->data, sizeof(void*) * capacity); + if (data) + { + v->data = data; + v->capacity = capacity; + } + return ((void)mlx_error(MLX_MEMFAIL)); +} + +void mlx_vector_init(mlx_vec_t* v, size_t elementSize) +{ + MLX_NONNULL(v); + + v->count = 0; + v->capacity = 1; + v->position = 0; + v->elementSize = elementSize; + if (!(v->data = malloc(elementSize * v->capacity))) + return ((void)mlx_error(MLX_MEMFAIL)); +} + +void mlx_vector_push_back(mlx_vec_t* v, void* item) +{ + MLX_NONNULL(v); + + if (v->capacity == v->count) + mlx_vector_resize(v, v->capacity * 2); + + memcpy(v->data + v->position, item, v->elementSize); + v->position += v->elementSize; + v->count++; +} + +void mlx_vector_set(mlx_vec_t* v, size_t index, void* item) +{ + MLX_NONNULL(v); + MLX_ASSERT(index >= 0 && index < v->count, "Out of bounds"); + + memcpy(v->data + (index * v->elementSize), item, v->elementSize); +} + +void* mlx_vector_get(mlx_vec_t* v, size_t index) +{ + MLX_NONNULL(v); + MLX_ASSERT(index >= 0 && index < v->count, "Out of bounds"); + + return (v->data + (index * v->elementSize)); +} + +void mlx_vector_delete(mlx_vec_t* v, size_t index) +{ + MLX_NONNULL(v); + MLX_ASSERT(index >= 0 && index < v->count, "Out of bounds"); + + if (index == 0) + { + if (v->count == 1) + v->position = 0; + else + { + memcpy(v->data, v->data + v->elementSize, v->elementSize * v->count - 1); + v->position -= v->elementSize; + } + } + else if(index == v->count - 1) + v->position -= v->elementSize; + else + { + memcpy(v->data + (index * v->elementSize), v->data + ((index + 1) * v->elementSize), v->elementSize * (v->count - index)); + v->position = v->elementSize * (v->count - 1); + } + + v->count--; + + if (v->count > 0 && v->count == v->capacity / 4) + mlx_vector_resize(v, v->capacity / 2); +} + +void mlx_vector_free(mlx_vec_t* v) +{ + free(v->data); +} From 5e782e8db0ab43f90e1cbf9a60fc410e9a067bc5 Mon Sep 17 00:00:00 2001 From: W2Wizard <63303990+W2Wizard@users.noreply.github.com> Date: Sun, 21 Aug 2022 14:04:35 +0200 Subject: [PATCH 4/5] Implement vector clear Co-authored-by: VNC --- src/utils/mlx_vec.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/utils/mlx_vec.c b/src/utils/mlx_vec.c index 5cf3153..37cad76 100644 --- a/src/utils/mlx_vec.c +++ b/src/utils/mlx_vec.c @@ -14,11 +14,11 @@ //= Private =// -static void mlx_vector_resize(mlx_vec_t* v, int capacity) +static void mlx_vector_resize(mlx_vec_t* v, int32_t capacity) { MLX_NONNULL(v); - void **data = realloc(v->data, sizeof(void*) * capacity); + void* data = realloc(v->data, v->elementSize * capacity); if (data) { v->data = data; @@ -51,7 +51,7 @@ void mlx_vector_push_back(mlx_vec_t* v, void* item) v->count++; } -void mlx_vector_set(mlx_vec_t* v, size_t index, void* item) +void mlx_vector_set(mlx_vec_t* v, int32_t index, void* item) { MLX_NONNULL(v); MLX_ASSERT(index >= 0 && index < v->count, "Out of bounds"); @@ -59,7 +59,7 @@ void mlx_vector_set(mlx_vec_t* v, size_t index, void* item) memcpy(v->data + (index * v->elementSize), item, v->elementSize); } -void* mlx_vector_get(mlx_vec_t* v, size_t index) +void* mlx_vector_get(mlx_vec_t* v, int32_t index) { MLX_NONNULL(v); MLX_ASSERT(index >= 0 && index < v->count, "Out of bounds"); @@ -67,7 +67,23 @@ void* mlx_vector_get(mlx_vec_t* v, size_t index) return (v->data + (index * v->elementSize)); } -void mlx_vector_delete(mlx_vec_t* v, size_t index) +void mlx_vector_swap(mlx_vec_t* v, int32_t srcIndex, int32_t dstIndex) +{ + MLX_NONNULL(v); + MLX_ASSERT(srcIndex >= 0 && srcIndex < v->count, "Src Out of bounds"); + MLX_ASSERT(dstIndex >= 0 && dstIndex < v->count, "Dst Out of bounds"); + + int32_t srcPosition = v->elementSize * srcIndex; + int32_t dstPosition = v->elementSize * dstIndex; + + void* temp = alloca(v->elementSize); + + memcpy(temp, v->data + srcPosition, v->elementSize); + memcpy(v->data + srcPosition, v->data + dstPosition, v->elementSize); + memcpy(v->data + dstPosition, temp, v->elementSize); +} + +void mlx_vector_delete(mlx_vec_t* v, int32_t index) { MLX_NONNULL(v); MLX_ASSERT(index >= 0 && index < v->count, "Out of bounds"); @@ -96,7 +112,15 @@ void mlx_vector_delete(mlx_vec_t* v, size_t index) mlx_vector_resize(v, v->capacity / 2); } +void mlx_vector_clear(mlx_vec_t* v) +{ + v->position = 0; + v->count = 0; +} + void mlx_vector_free(mlx_vec_t* v) { + mlx_vector_clear(v); free(v->data); + v->capacity = 0; } From 9552fc1f927d453eee036a59f68ca2a3e52946f8 Mon Sep 17 00:00:00 2001 From: W2Wizard <63303990+W2Wizard@users.noreply.github.com> Date: Sun, 21 Aug 2022 16:45:06 +0200 Subject: [PATCH 5/5] Rewrite drawing Co-authored-by: VNC --- include/MLX42/MLX42_Int.h | 16 ++++--- src/mlx_exit.c | 2 +- src/mlx_images.c | 71 +++++++++++++++++-------------- src/mlx_init.c | 1 + src/mlx_loop.c | 19 +++------ src/utils/mlx_render_queue_sort.c | 51 ++++++++++++++++++++++ src/utils/mlx_vec.c | 22 ++++++---- 7 files changed, 121 insertions(+), 61 deletions(-) create mode 100644 src/utils/mlx_render_queue_sort.c diff --git a/include/MLX42/MLX42_Int.h b/include/MLX42/MLX42_Int.h index ea61470..d0f0462 100644 --- a/include/MLX42/MLX42_Int.h +++ b/include/MLX42/MLX42_Int.h @@ -195,7 +195,7 @@ typedef struct mlx_ctx mlx_list_t* hooks; mlx_list_t* images; - mlx_list_t* render_queue; + mlx_vec_t render_queue; int32_t instance_count; mlx_scroll_t scroll_hook; @@ -216,6 +216,7 @@ typedef struct draw_queue { mlx_image_t* image; int32_t instanceid; + int32_t caluclatedDepth; } draw_queue_t; // Image context. @@ -266,15 +267,18 @@ uint32_t mlx_rgba_to_mono(uint32_t color); int32_t mlx_atoi_base(const char* str, int32_t base); uint64_t mlx_fnv_hash(char* str, size_t len); +void mlx_render_queue_sort(mlx_vec_t *render_queue); + //= Image Helper Functions =// int32_t mlx_image_calculate_max_depth(mlx_image_t *image); //= Vector Functions =// -void mlx_vector_init(mlx_vec_t* v, size_t elementSize); -void mlx_vector_push_back(mlx_vec_t* v, void* item); -void mlx_vector_set(mlx_vec_t* v, size_t index, void* item); -void* mlx_vector_get(mlx_vec_t* v, size_t index); -void mlx_vector_delete(mlx_vec_t* v, size_t index); +bool mlx_vector_init(mlx_vec_t* v, size_t elementSize); +bool mlx_vector_push_back(mlx_vec_t* v, void* item); +void mlx_vector_set(mlx_vec_t* v, int32_t index, void* item); +void* mlx_vector_get(mlx_vec_t* v, int32_t index); +bool mlx_vector_delete(mlx_vec_t* v, int32_t index); void mlx_vector_free(mlx_vec_t* v); +void mlx_vector_swap(mlx_vec_t* v, int32_t srcIndex, int32_t dstIndex); #endif diff --git a/src/mlx_exit.c b/src/mlx_exit.c index 138c787..488d71d 100644 --- a/src/mlx_exit.c +++ b/src/mlx_exit.c @@ -41,7 +41,7 @@ void mlx_terminate(mlx_t* mlx) glfwTerminate(); mlx_lstclear((mlx_list_t**)(&mlxctx->hooks), &free); - mlx_lstclear((mlx_list_t**)(&mlxctx->render_queue), &free); mlx_lstclear((mlx_list_t**)(&mlxctx->images), &mlx_free_image); + mlx_vector_free(&mlxctx->render_queue); mlx_freen(2, mlxctx, mlx); } diff --git a/src/mlx_images.c b/src/mlx_images.c index 76e29df..0a9e154 100644 --- a/src/mlx_images.c +++ b/src/mlx_images.c @@ -84,20 +84,29 @@ void mlx_draw_instance(mlx_ctx_t* mlx, mlx_image_t* img, mlx_instance_t* instanc mlx_flush_batch(mlx); } -mlx_instance_t* mlx_grow_instances(mlx_image_t* img, bool* did_realloc) +static mlx_instance_t* mlx_grow_instances(mlx_image_t* img) { + size_t new_size = 0; mlx_image_ctx_t* const ctx = img->context; - if (img->count >= ctx->instances_capacity) + mlx_instance_t* temp = NULL; + + // Do we need to grow ? + if (img->count + 1 >= ctx->instances_capacity) { if (ctx->instances_capacity == 0) - ctx->instances_capacity = img->count; + new_size++; else - ctx->instances_capacity *= 2; - *did_realloc = true; - return realloc(img->instances, ctx->instances_capacity * sizeof(mlx_instance_t)); + { + new_size = ctx->instances_capacity * 2; + } + + if (!(temp = realloc(img->instances, new_size * sizeof(mlx_instance_t)))) + return (NULL); + ctx->instances_capacity = new_size; + img->instances = temp; } - *did_realloc = false; - return img->instances; + img->count++; + return (img->instances); } //= Public =// @@ -109,37 +118,29 @@ int32_t mlx_image_to_window(mlx_t* mlx, mlx_image_t* img, int32_t x, int32_t y) mlx_ctx_t* mlxctx = mlx->context; - // Allocate buffers... - img->count++; - bool did_realloc; - mlx_instance_t* instances = mlx_grow_instances(img, &did_realloc); - draw_queue_t* queue = calloc(1, sizeof(draw_queue_t)); - if (!instances || !queue) + // Grow instances to fit new instance. + mlx_instance_t* instances; + + if (!(instances = mlx_grow_instances(img))) { - if (did_realloc) - free(instances); - return (free(queue), mlx_error(MLX_MEMFAIL), -1); + mlx_error(MLX_MEMFAIL); + return (-1); } - // Set data... - queue->image = img; - int32_t index = queue->instanceid = img->count - 1; - + const int32_t index = img->count - 1; img->instances = instances; img->instances[index].x = x; img->instances[index].y = y; img->instances[index].custom_depth = -1; img->instances[index].enabled = true; - // Add draw call... - mlx_list_t* templst; - if ((templst = mlx_lstnew(queue))) - { - mlx_lstadd_back(&(mlxctx->render_queue), templst); - mlxctx->instance_count++; - return (index); - } - return (mlx_freen(2, instances, queue), mlx_error(MLX_MEMFAIL), -1); + // Add drawcall + draw_queue_t queue = (draw_queue_t){ img, img->count - 1, 0}; + if (!mlx_vector_push_back(&(mlxctx->render_queue), &queue)) + return (-1); + + mlxctx->instance_count++; + return (index); } mlx_image_t *mlx_new_image(mlx_t* mlx, uint32_t width, uint32_t height) @@ -193,9 +194,13 @@ void mlx_delete_image(mlx_t* mlx, mlx_image_t* image) mlx_ctx_t* mlxctx = mlx->context; // Delete all instances in the render queue - mlx_list_t* quelst; - while ((quelst = mlx_lstremove(&mlxctx->render_queue, image, &mlx_equal_inst))) - mlx_freen(2, quelst->content, quelst); + for(int32_t i = mlxctx->render_queue.count - 1; i >= 0 ; i--) + { + draw_queue_t* element = mlx_vector_get(&mlxctx->render_queue, i); + + if (element->image == image) + mlx_vector_delete(&mlxctx->render_queue, i); + } mlxctx->instance_count -= image->count; diff --git a/src/mlx_init.c b/src/mlx_init.c index de73356..a164188 100644 --- a/src/mlx_init.c +++ b/src/mlx_init.c @@ -170,6 +170,7 @@ mlx_t* mlx_init(int32_t width, int32_t height, const char* title, bool resize) mlx->height = height; mlxctx->initialWidth = width; mlxctx->initialHeight = height; + mlx_vector_init(&mlxctx->render_queue, sizeof(draw_queue_t)); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); diff --git a/src/mlx_loop.c b/src/mlx_loop.c index 6caade6..75d2549 100644 --- a/src/mlx_loop.c +++ b/src/mlx_loop.c @@ -31,8 +31,9 @@ static void mlx_render_images(mlx_t* mlx) { mlx_ctx_t* mlxctx = mlx->context; mlx_list_t* imglst = mlxctx->images; - - // Sort queue! + mlx_vec_t *render_queue = &mlxctx->render_queue; + + mlx_render_queue_sort(render_queue); // Upload image textures to GPU while (imglst) @@ -46,19 +47,13 @@ static void mlx_render_images(mlx_t* mlx) } // Execute draw calls - int32_t depth = 0; - mlx_list_t* render_queue = mlxctx->render_queue; - while (render_queue) + for (int32_t i = 0; i < render_queue->count; i++) { - draw_queue_t* drawcall = render_queue->content; + draw_queue_t* drawcall = mlx_vector_get(render_queue, i); mlx_instance_t* instance = &drawcall->image->instances[drawcall->instanceid]; - int32_t instanceDepth = instance->custom_depth > 0 ? instance->custom_depth : depth++; - - if (drawcall && drawcall->image->enabled && instance->enabled) - mlx_draw_instance(mlx->context, drawcall->image, instance, instanceDepth); - - render_queue = render_queue->next; + if (drawcall->image->enabled && instance->enabled) + mlx_draw_instance(mlx->context, drawcall->image, instance, drawcall->caluclatedDepth); } } diff --git a/src/utils/mlx_render_queue_sort.c b/src/utils/mlx_render_queue_sort.c new file mode 100644 index 0000000..38163c1 --- /dev/null +++ b/src/utils/mlx_render_queue_sort.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* mlx_render_queue_sort.c :+: :+: */ +/* +:+ */ +/* By: W2Wizard +#+ */ +/* +#+ */ +/* Created: 2022/08/20 21:33:52 by W2Wizard #+# #+# */ +/* Updated: 2022/08/20 21:33:52 by W2Wizard ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "MLX42/MLX42_Int.h" + +void mlx_render_queue_sort(mlx_vec_t* render_queue) +{ + if(render_queue->count < 1) + return; + + int32_t currentDepth = 0; + for (int32_t i = 0; i < render_queue->count; i++) + { + draw_queue_t* element = mlx_vector_get(render_queue, i); + mlx_instance_t* instance = &element->image->instances[element->instanceid]; + + element->caluclatedDepth = instance->custom_depth > 0 ? instance->custom_depth : currentDepth++; + // printf("%i -> %i\n", element->instanceid, element->caluclatedDepth); + } + + for (int32_t i = 0; i < render_queue->count; i++) + { + bool hasSwap = false; + for (int32_t j = 0; j < render_queue->count - i - 1; j++) + { + draw_queue_t* aElement = mlx_vector_get(render_queue, j); + draw_queue_t* bElement = mlx_vector_get(render_queue, j + 1); + + if (aElement->caluclatedDepth > bElement->caluclatedDepth) + { + mlx_vector_swap(render_queue, j, j + 1); + hasSwap = true; + } + } + + if (!hasSwap) + break; + } + + // printf("firstInstanceToRender -> %i\n", ((draw_queue_t*)mlx_vector_get(render_queue, 0))->instanceid); + // printf("lastInstanceToRender -> %i\n", ((draw_queue_t*)mlx_vector_get(render_queue, render_queue->count - 1))->instanceid); +} \ No newline at end of file diff --git a/src/utils/mlx_vec.c b/src/utils/mlx_vec.c index 37cad76..628623c 100644 --- a/src/utils/mlx_vec.c +++ b/src/utils/mlx_vec.c @@ -14,7 +14,7 @@ //= Private =// -static void mlx_vector_resize(mlx_vec_t* v, int32_t capacity) +static bool mlx_vector_resize(mlx_vec_t* v, int32_t capacity) { MLX_NONNULL(v); @@ -23,11 +23,12 @@ static void mlx_vector_resize(mlx_vec_t* v, int32_t capacity) { v->data = data; v->capacity = capacity; + return (true); } - return ((void)mlx_error(MLX_MEMFAIL)); + return (mlx_error(MLX_MEMFAIL)); } -void mlx_vector_init(mlx_vec_t* v, size_t elementSize) +bool mlx_vector_init(mlx_vec_t* v, size_t elementSize) { MLX_NONNULL(v); @@ -36,19 +37,21 @@ void mlx_vector_init(mlx_vec_t* v, size_t elementSize) v->position = 0; v->elementSize = elementSize; if (!(v->data = malloc(elementSize * v->capacity))) - return ((void)mlx_error(MLX_MEMFAIL)); + return (mlx_error(MLX_MEMFAIL)); + return (true); } -void mlx_vector_push_back(mlx_vec_t* v, void* item) +bool mlx_vector_push_back(mlx_vec_t* v, void* item) { MLX_NONNULL(v); - if (v->capacity == v->count) - mlx_vector_resize(v, v->capacity * 2); + if (v->capacity == v->count && !mlx_vector_resize(v, v->capacity * 2)) + return (false); memcpy(v->data + v->position, item, v->elementSize); v->position += v->elementSize; v->count++; + return (true); } void mlx_vector_set(mlx_vec_t* v, int32_t index, void* item) @@ -83,7 +86,7 @@ void mlx_vector_swap(mlx_vec_t* v, int32_t srcIndex, int32_t dstIndex) memcpy(v->data + dstPosition, temp, v->elementSize); } -void mlx_vector_delete(mlx_vec_t* v, int32_t index) +bool mlx_vector_delete(mlx_vec_t* v, int32_t index) { MLX_NONNULL(v); MLX_ASSERT(index >= 0 && index < v->count, "Out of bounds"); @@ -109,7 +112,8 @@ void mlx_vector_delete(mlx_vec_t* v, int32_t index) v->count--; if (v->count > 0 && v->count == v->capacity / 4) - mlx_vector_resize(v, v->capacity / 2); + return (mlx_vector_resize(v, v->capacity / 2)); + return (true); } void mlx_vector_clear(mlx_vec_t* v)