texture.c
1 /* ************************************************************************** */ 2 /* */ 3 /* ::: :::::::: */ 4 /* texture.c :+: :+: :+: */ 5 /* +:+ +:+ +:+ */ 6 /* By: gychoi <gychoi@student.42seoul.kr> +#+ +:+ +#+ */ 7 /* +#+#+#+#+#+ +#+ */ 8 /* Created: 2023/05/16 17:34:01 by gychoi #+# #+# */ 9 /* Updated: 2023/05/17 21:45:21 by gychoi ### ########.fr */ 10 /* */ 11 /* ************************************************************************** */ 12 13 #include "pracrt.h" 14 #include "utils.h" 15 #include "texture.h" 16 17 t_color3 get_clamped(t_texture *texture, int i, int j) 18 { 19 double r; 20 double g; 21 double b; 22 23 i = clamp(i, 0, texture->width - 1); 24 j = clamp(j, 0, texture->height - 1); 25 26 r = texture->image[(i + texture->width * j) * texture->channels + 0] / 255.0f; 27 g = texture->image[(i + texture->width * j) * texture->channels + 1] / 255.0f; 28 b = texture->image[(i + texture->width * j) * texture->channels + 2] / 255.0f; 29 30 return (color3(r, g, b)); 31 } 32 33 t_color3 get_wrapped(t_texture *texture, int i, int j) 34 { 35 double r; 36 double g; 37 double b; 38 39 i %= texture->width; 40 j %= texture->height; 41 42 if (i < 0) 43 i += texture->width; 44 if (j < 0) 45 j += texture->height; 46 47 r = texture->image[(i + texture->width * j) * texture->channels + 0] / 255.0f; 48 g = texture->image[(i + texture->width * j) * texture->channels + 1] / 255.0f; 49 b = texture->image[(i + texture->width * j) * texture->channels + 2] / 255.0f; 50 51 return (color3(r, g, b)); 52 } 53 54 t_point3 sample_point(t_texture *texture, t_vec2 *uv) 55 { 56 t_vec2 xy; 57 int i; 58 int j; 59 60 xy = v2sub(v2mult(*uv, vec2((double)texture->width, (double)texture->height)), vec2(0.5f, 0.5f)); 61 i = round(xy.x); 62 j = round(xy.y); 63 64 return (get_wrapped(texture, i, j)); 65 } 66 67 t_point3 interpolate_bilinear(double dx, double dy, t_vec3 c00, t_vec3 c10, t_vec3 c01, t_vec3 c11) 68 { 69 t_vec3 a; 70 t_vec3 b; 71 72 a = vadd(vmults(c00, (1.0f - dx)), vmults(c10, dx)); 73 b = vadd(vmults(c01, (1.0f - dx)), vmults(c11, dx)); 74 return (vadd(vmults(a, (1.0f - dy)), vmults(b, dy))); 75 } 76 77 t_point3 sample_linear(t_texture *texture, t_vec2 *uv) 78 { 79 t_vec2 xy; 80 int i; 81 int j; 82 double dx; 83 double dy; 84 85 xy = v2sub(v2mult(*uv, vec2((double)texture->width, (double)texture->height)), vec2(0.5f, 0.5f)); 86 i = (int)(floor(xy.x)); 87 j = (int)(floor(xy.y)); 88 dx = xy.x - (double)i; 89 dy = xy.y - (double)j; 90 return (interpolate_bilinear(dx, dy, get_wrapped(texture, i, j), get_wrapped(texture, i + 1, j), get_wrapped(texture, i, j + 1), get_wrapped(texture, i + 1, j + 1))); 91 } 92 93 t_texture *generate_sample_texture_image(int width, int height, t_vec3 *sample_image) 94 { 95 t_texture *texture; 96 double *image; 97 t_color3 color; 98 99 texture = malloc(sizeof(t_texture)); 100 if (!texture) 101 return (NULL); 102 texture->width = width; 103 texture->height = height; 104 texture->channels = 3; 105 image = malloc(sizeof(double) * width * height * 3); 106 for (int j = 0; j < height; j++) 107 for (int i = 0; i < width; i++) 108 { 109 color = sample_image[i + j * width]; 110 image[(i + width * j) * 3 + 0] = color.x * 255; 111 image[(i + width * j) * 3 + 1] = color.y * 255; 112 image[(i + width * j) * 3 + 2] = color.z * 255; 113 } 114 texture->image = image; 115 return (texture); 116 } 117 118 t_texture *generate_texture_image(int width, int height, void *texture_image) 119 { 120 t_texture *texture; 121 unsigned int *data; 122 unsigned int pixel; 123 double *image; 124 t_color3 color; 125 int bpp, size_l, endian; 126 127 texture = malloc(sizeof(t_texture)); 128 if (!texture) 129 return (NULL); 130 image = malloc(sizeof(double) * width * height * 3); 131 if (!image) 132 return (NULL); 133 data = (unsigned int *)mlx_get_data_addr(texture_image, &bpp, &size_l, &endian); 134 135 for (int j = 0; j < height; j++) 136 for (int i = 0; i < width; i++) 137 { 138 pixel = data[size_l / (bpp / 8) * j + i]; 139 image[(i + width * j) * 3 + 0] = (pixel & (0xFF << 16)) >> 16; 140 image[(i + width * j) * 3 + 1] = (pixel & (0xFF << 8)) >> 8; 141 image[(i + width * j) * 3 + 2] = pixel & 0xFF; 142 } 143 144 texture->width = width; 145 texture->height = height; 146 texture->channels = 3; 147 texture->image = image; 148 return (texture); 149 }