MLX42 1.0
MLX42
Loading...
Searching...
No Matches
mlx_images.c File Reference
#include "MLX42/MLX42_Int.h"
Include dependency graph for mlx_images.c:

Go to the source code of this file.

Functions

void mlx_flush_batch (mlx_ctx_t *mlx)
 
static int8_t mlx_bind_texture (mlx_ctx_t *mlx, mlx_image_t *img)
 
void mlx_draw_instance (mlx_ctx_t *mlx, mlx_image_t *img, mlx_instance_t *instance)
 
mlx_instance_tmlx_grow_instances (mlx_image_t *img, bool *did_realloc)
 
void mlx_set_instance_depth (mlx_instance_t *instance, int32_t zdepth)
 
int32_t mlx_image_to_window (mlx_t *mlx, mlx_image_t *img, int32_t x, int32_t y)
 
mlx_image_tmlx_new_image (mlx_t *mlx, uint32_t width, uint32_t height)
 
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)
 

Function Documentation

◆ mlx_bind_texture()

static int8_t mlx_bind_texture ( mlx_ctx_t mlx,
mlx_image_t img 
)
static

Definition at line 30 of file mlx_images.c.

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}
GLuint texture
Definition glad.h:2899
#define GL_TEXTURE0
Definition glad.h:705
#define glBindTexture
Definition glad.h:2901
GLuint GLsizei GLsizei * length
Definition glad.h:3372
int GLint
Definition glad.h:98
#define GL_TEXTURE_2D
Definition glad.h:243
GLint void * img
Definition glad.h:3003
#define glActiveTexture
Definition glad.h:2981
void mlx_flush_batch(mlx_ctx_t *mlx)
Definition mlx_images.c:17
Definition MLX42.h:361
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlx_delete_image()

void mlx_delete_image ( mlx_t mlx,
mlx_image_t image 
)

Deleting an image will remove it from the render queue as well as any and all instances it might have. Additionally, just as extra measures sets all the data to NULL.

If you simply wish to stop rendering an image without de-allocation set the 'enabled' boolean in the image struct.

Parameters
[in]mlxThe MLX instance handle.
[in]imageThe image to delete.

Definition at line 204 of file mlx_images.c.

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}
#define MLX_NONNULL(var)
Definition MLX42_Int.h:46
mlx_list_t * mlx_lstremove(mlx_list_t **lst, void *value, bool(*comp)(void *, void *))
Definition mlx_list.c:100
bool mlx_equal_image(void *lstcontent, void *value)
Definition mlx_compare.c:17
bool mlx_freen(int32_t count,...)
Definition mlx_utils.c:89
bool mlx_equal_inst(void *lstcontent, void *value)
Definition mlx_compare.c:25
GLenum GLenum GLsizei void * image
Definition glad.h:5132
#define glDeleteTextures
Definition glad.h:2904
void * context
Definition MLX42.h:363
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlx_draw_instance()

void mlx_draw_instance ( mlx_ctx_t mlx,
mlx_image_t img,
mlx_instance_t instance 
)

Internal function to draw a single instance of an image to the screen.

Definition at line 63 of file mlx_images.c.

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}
struct vertex vertex_t
#define MLX_BATCH_SIZE
Definition MLX42_Int.h:40
GLdouble GLdouble z
Definition glad.h:2301
GLint y
Definition glad.h:1965
GLdouble x
Definition glad.h:2847
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlx_flush_batch()

void mlx_flush_batch ( mlx_ctx_t mlx)

Definition at line 17 of file mlx_images.c.

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}
#define glBindBuffer
Definition glad.h:3292
#define GL_TRIANGLES
Definition glad.h:145
#define GL_ARRAY_BUFFER
Definition glad.h:857
#define glDrawArrays
Definition glad.h:2871
#define glBufferData
Definition glad.h:3304
#define GL_STATIC_DRAW
Definition glad.h:871
Here is the caller graph for this function:

◆ mlx_grow_instances()

mlx_instance_t * mlx_grow_instances ( mlx_image_t img,
bool did_realloc 
)

Definition at line 87 of file mlx_images.c.

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}
size_t instances_capacity
Definition MLX42_Int.h:209
Here is the caller graph for this function:

◆ mlx_image_to_window()

int32_t mlx_image_to_window ( mlx_t mlx,
mlx_image_t img,
int32_t  x,
int32_t  y 
)

Draws a new instance of an image, it will then share the same pixel buffer as the image.

NOTE: Keep in mind that the instance array gets reallocated, try to store the return value to the instance! NOT the pointer! It will become invalid!

WARNING: Try to display as few images on the window as possible, drawing too many images will cause a loss in performance!

Parameters
[in]mlxThe MLX instance handle.
[in]imgThe image to draw on the screen.
[in]xThe X position.
[in]yThe Y position.
Returns
Index to the instance, or -1 on failure.

Definition at line 121 of file mlx_images.c.

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}
@ MLX_MEMFAIL
Definition MLX42.h:383
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
bool sort_queue
Definition mlx_init.c:162
mlx_list_t * mlx_lstnew(void *content)
Definition mlx_list.c:45
GLuint index
Definition glad.h:3345
mlx_instance_t * mlx_grow_instances(mlx_image_t *img, bool *did_realloc)
Definition mlx_images.c:87
int32_t x
Definition MLX42.h:303
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlx_new_image()

mlx_image_t * mlx_new_image ( mlx_t mlx,
uint32_t  width,
uint32_t  height 
)

Creates and allocates a new image buffer.

Parameters
[in]mlxThe MLX instance handle.
[in]widthThe desired width of the image.
[in]heightThe desired height of the image.
Returns
Pointer to the image buffer, if it failed to allocate then NULL.

Definition at line 161 of file mlx_images.c.

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}
@ MLX_INVDIM
Definition MLX42.h:378
#define GL_TEXTURE_MIN_FILTER
Definition glad.h:305
#define GL_TEXTURE_WRAP_S
Definition glad.h:306
#define glTexParameteri
Definition glad.h:1976
GLint GLsizei GLsizei height
Definition glad.h:1965
GLint GLsizei width
Definition glad.h:1965
#define GL_NEAREST
Definition glad.h:298
#define glGenTextures
Definition glad.h:2907
#define GL_TEXTURE_WRAP_T
Definition glad.h:307
#define GL_TEXTURE_MAG_FILTER
Definition glad.h:304
#define GL_CLAMP_TO_EDGE
Definition glad.h:690
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlx_resize_image()

bool mlx_resize_image ( mlx_image_t img,
uint32_t  nwidth,
uint32_t  nheight 
)

Allows you to resize an image, a new pixel buffer is allocated to fit & the previous data is scaled to fit the new size.

Parameters
[in]imgThe image to resize.
[in]nwidthThe new width.
[in]nheightThe new height.
Returns
True if image was resized or false on error.

Definition at line 224 of file mlx_images.c.

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}
#define BPP
Definition MLX42_Int.h:42
GLint j
Definition glad.h:2733
#define glTexImage2D
Definition glad.h:1985
#define GL_UNSIGNED_BYTE
Definition glad.h:251
#define GL_RGBA
Definition glad.h:286
Here is the call graph for this function:

◆ mlx_set_instance_depth()

void mlx_set_instance_depth ( mlx_instance_t instance,
int32_t  zdepth 
)

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 it's not conflicting by being on the same layer as another image.

Parameters
[in]instanceThe instance on which to change the depth.
[in]zdepthThe new depth value.

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.

Definition at line 105 of file mlx_images.c.

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}