MLX42 1.0
MLX42
Loading...
Searching...
No Matches
mlx_images.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* :::::::: */
4/* mlx_images.c :+: :+: */
5/* +:+ */
6/* By: W2Wizard <main@w2wizard.dev> +#+ */
7/* +#+ */
8/* Created: 2021/12/28 02:29:06 by W2Wizard #+# #+# */
9/* Updated: 2023/03/30 16:36:39 by ntamayo- ######## odam.nl */
10/* */
11/* ************************************************************************** */
12
13#include "MLX42/MLX42_Int.h"
14
15//= Private =//
16
18{
19 if (mlx->batch_size <= 0)
20 return;
21
23 glBufferData(GL_ARRAY_BUFFER, mlx->batch_size * sizeof(vertex_t), mlx->batch_vertices, GL_STATIC_DRAW);
24 glDrawArrays(GL_TRIANGLES, 0, mlx->batch_size);
25
26 mlx->batch_size = 0;
27 memset(mlx->bound_textures, 0, sizeof(mlx->bound_textures));
28}
29
31{
32 const GLint handle = (GLint)((mlx_image_ctx_t*)img->context)->texture;
33
34 // Attempt to bind the texture, or obtain the index if it is already bound.
35 for (int8_t i = 0; i < 16; i++)
36 {
37 if (mlx->bound_textures[i] == handle)
38 return (i);
39
40 if (mlx->bound_textures[i] == 0)
41 {
42 mlx->bound_textures[i] = handle;
43
46 return (i);
47 }
48 }
49
50 // If no free slot was found, flush the batch and assign the texture to the first available slot
52
53 mlx->bound_textures[0] = handle;
56 return (0);
57}
58
59/**
60 * Internal function to draw a single instance of an image
61 * to the screen.
62 */
64{
65 float w = (float) img->width;
66 float h = (float) img->height;
67 float x = (float) instance->x;
68 float y = (float) instance->y;
69 float z = (float) instance->z;
71
72 vertex_t vertices[6] = {
73 (vertex_t){x, y, z, 0.f, 0.f, tex},
74 (vertex_t){x + w, y + h, z, 1.f, 1.f, tex},
75 (vertex_t){x + w, y, z, 1.f, 0.f, tex},
76 (vertex_t){x, y, z, 0.f, 0.f, tex},
77 (vertex_t){x, y + h, z, 0.f, 1.f, tex},
78 (vertex_t){x + w, y + h, z, 1.f, 1.f, tex},
79 };
80 memmove(mlx->batch_vertices + mlx->batch_size, vertices, sizeof(vertices));
81 mlx->batch_size += 6;
82
83 if (mlx->batch_size >= MLX_BATCH_SIZE)
85}
86
88{
89 mlx_image_ctx_t* const ctx = img->context;
90 if (img->count >= ctx->instances_capacity)
91 {
92 if (ctx->instances_capacity == 0)
93 ctx->instances_capacity = img->count;
94 else
95 ctx->instances_capacity *= 2;
96 *did_realloc = true;
97 return realloc(img->instances, ctx->instances_capacity * sizeof(mlx_instance_t));
98 }
99 *did_realloc = false;
100 return img->instances;
101}
102
103//= Public =//
104
106{
108
109 if (instance->z == zdepth)
110 return;
111 instance->z = zdepth;
112
113 /**
114 * NOTE: The reason why we don't sort directly is that
115 * the user might call this function multiple times in a row and we don't
116 * want to sort for every change. Pre-loop wise that is.
117 */
118 sort_queue = true;
119}
120
122{
125
126 // Allocate buffers...
127 img->count++;
128 bool did_realloc;
130 draw_queue_t* queue = calloc(1, sizeof(draw_queue_t));
131 if (!instances || !queue)
132 {
133 if (did_realloc)
134 free(instances);
135 return (free(queue), mlx_error(MLX_MEMFAIL), -1);
136 }
137
138 // Set data...
139 queue->image = img;
140 int32_t index = queue->instanceid = img->count - 1;
141 img->instances = instances;
142 img->instances[index].x = x;
143 img->instances[index].y = y;
144
145 // NOTE: We keep updating the Z for the convenience of the user.
146 // Always update Z depth to prevent overlapping images by default.
147 img->instances[index].z = ((mlx_ctx_t*)mlx->context)->zdepth++;
148 img->instances[index].enabled = true;
149
150 // Add draw call...
151 sort_queue = true;
153 if ((templst = mlx_lstnew(queue)))
154 {
155 mlx_lstadd_front(&((mlx_ctx_t*)mlx->context)->render_queue, templst);
156 return (index);
157 }
158 return (mlx_freen(2, instances, queue), mlx_error(MLX_MEMFAIL), -1);
159}
160
162{
164
165 if (!width || !height || width > INT16_MAX || height > INT16_MAX)
166 return ((void*)mlx_error(MLX_INVDIM));
167
168 const mlx_ctx_t* mlxctx = mlx->context;
169 mlx_image_t* newimg = calloc(1, sizeof(mlx_image_t));
171 if (!newimg || !newctx)
172 {
174 return ((void *)mlx_error(MLX_MEMFAIL));
175 }
176 newimg->enabled = true;
177 newimg->context = newctx;
178 (*(uint32_t*)&newimg->width) = width;
179 (*(uint32_t*)&newimg->height) = height;
180 if (!(newimg->pixels = calloc(width * height, sizeof(int32_t))))
181 {
183 return ((void *)mlx_error(MLX_MEMFAIL));
184 }
185
187 if (!(newentry = mlx_lstnew(newimg)))
188 {
189 mlx_freen(3, newimg->pixels, newimg->context, newimg);
190 return ((void *)mlx_error(MLX_MEMFAIL));
191 }
192
193 // Generate OpenGL texture
194 glGenTextures(1, &newctx->texture);
201 return (newimg);
202}
203
205{
208
210
211 // Delete all instances in the render queue
213 while ((quelst = mlx_lstremove(&mlxctx->render_queue, image, &mlx_equal_inst)))
214 mlx_freen(2, quelst->content, quelst);
215
217 if ((imglst = mlx_lstremove(&mlxctx->images, image, &mlx_equal_image)))
218 {
219 glDeleteTextures(1, &((mlx_image_ctx_t*)image->context)->texture);
220 mlx_freen(5, image->pixels, image->instances, image->context, imglst, image);
221 }
222}
223
225{
227
228 if (!nwidth || !nheight || nwidth > INT16_MAX || nheight > INT16_MAX)
229 return (mlx_error(MLX_INVDIM));
230 if (nwidth != img->width || nheight != img->height)
231 {
232 uint32_t* origin = (uint32_t*)img->pixels;
233 float wstep = (float)img->width / nwidth;
234 float hstep = (float)img->height / nheight;
235
237 if (!tempbuff)
238 return (mlx_error(MLX_MEMFAIL));
239 img->pixels = tempbuff;
241
242 uint32_t* destin = (uint32_t*)img->pixels;
243 for (uint32_t j = 0; j < nheight; j++)
244 for (uint32_t i = 0; i < nwidth; i++)
245 destin[j * nwidth + i] = origin[(uint32_t)(j * hstep) * img->width + (uint32_t)(i * wstep)];
246 (*(uint32_t*)&img->width) = nwidth;
247 (*(uint32_t*)&img->height) = nheight;
248 free(origin);
249 }
250 return (true);
251}
@ MLX_MEMFAIL
Definition MLX42.h:383
@ MLX_INVDIM
Definition MLX42.h:378
#define MLX_NONNULL(var)
Definition MLX42_Int.h:46
void mlx_lstadd_front(mlx_list_t **lst, mlx_list_t *new)
Definition mlx_list.c:81
bool mlx_error(mlx_errno_t val)
Definition mlx_error.c:43
mlx_list_t * mlx_lstremove(mlx_list_t **lst, void *value, bool(*comp)(void *, void *))
Definition mlx_list.c:100
struct vertex vertex_t
bool mlx_equal_image(void *lstcontent, void *value)
Definition mlx_compare.c:17
#define BPP
Definition MLX42_Int.h:42
bool mlx_freen(int32_t count,...)
Definition mlx_utils.c:89
bool mlx_equal_inst(void *lstcontent, void *value)
Definition mlx_compare.c:25
#define MLX_BATCH_SIZE
Definition MLX42_Int.h:40
bool sort_queue
Definition mlx_init.c:162
mlx_list_t * mlx_lstnew(void *content)
Definition mlx_list.c:45
GLuint texture
Definition glad.h:2899
#define GL_TEXTURE0
Definition glad.h:705
#define GL_TEXTURE_MIN_FILTER
Definition glad.h:305
GLdouble GLdouble z
Definition glad.h:2301
GLint j
Definition glad.h:2733
#define GL_TEXTURE_WRAP_S
Definition glad.h:306
#define glBindBuffer
Definition glad.h:3292
GLuint index
Definition glad.h:3345
#define glTexParameteri
Definition glad.h:1976
GLint y
Definition glad.h:1965
GLint GLsizei GLsizei height
Definition glad.h:1965
#define GL_TRIANGLES
Definition glad.h:145
GLint GLsizei width
Definition glad.h:1965
#define GL_ARRAY_BUFFER
Definition glad.h:857
GLdouble x
Definition glad.h:2847
#define glTexImage2D
Definition glad.h:1985
#define GL_NEAREST
Definition glad.h:298
#define GL_UNSIGNED_BYTE
Definition glad.h:251
#define glGenTextures
Definition glad.h:2907
GLenum GLenum GLsizei void * image
Definition glad.h:5132
#define glDrawArrays
Definition glad.h:2871
#define glBufferData
Definition glad.h:3304
#define glBindTexture
Definition glad.h:2901
#define GL_RGBA
Definition glad.h:286
#define GL_STATIC_DRAW
Definition glad.h:871
GLuint GLsizei GLsizei * length
Definition glad.h:3372
#define GL_TEXTURE_WRAP_T
Definition glad.h:307
#define GL_TEXTURE_MAG_FILTER
Definition glad.h:304
int GLint
Definition glad.h:98
#define GL_TEXTURE_2D
Definition glad.h:243
#define GL_CLAMP_TO_EDGE
Definition glad.h:690
GLint void * img
Definition glad.h:3003
#define glDeleteTextures
Definition glad.h:2904
#define glActiveTexture
Definition glad.h:2981
GLfloat GLfloat GLfloat GLfloat h
Definition glad.h:4546
GLdouble GLdouble GLdouble w
Definition glad.h:2325
static int8_t mlx_bind_texture(mlx_ctx_t *mlx, mlx_image_t *img)
Definition mlx_images.c:30
int32_t mlx_image_to_window(mlx_t *mlx, mlx_image_t *img, int32_t x, int32_t y)
Definition mlx_images.c:121
void mlx_set_instance_depth(mlx_instance_t *instance, int32_t zdepth)
Definition mlx_images.c:105
void mlx_flush_batch(mlx_ctx_t *mlx)
Definition mlx_images.c:17
void mlx_draw_instance(mlx_ctx_t *mlx, mlx_image_t *img, mlx_instance_t *instance)
Definition mlx_images.c:63
bool mlx_resize_image(mlx_image_t *img, uint32_t nwidth, uint32_t nheight)
Definition mlx_images.c:224
mlx_instance_t * mlx_grow_instances(mlx_image_t *img, bool *did_realloc)
Definition mlx_images.c:87
void mlx_delete_image(mlx_t *mlx, mlx_image_t *image)
Definition mlx_images.c:204
mlx_image_t * mlx_new_image(mlx_t *mlx, uint32_t width, uint32_t height)
Definition mlx_images.c:161
size_t instances_capacity
Definition MLX42_Int.h:209
int32_t x
Definition MLX42.h:303
Definition MLX42.h:361
void * context
Definition MLX42.h:363