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  }