-
Notifications
You must be signed in to change notification settings - Fork 8
How to create linear gradient?
Here we will consider how to find the color between any two color points through linear interpolation.
First of all we need to find current point position between two points with known colors. Position value must be expressed in percentages.
The following function will help you find this value:
double percent(int start, int end, int current)
{
double placement;
double distance;
placement = current - start;
distance = end - start;
return ((distance == 0) ? 1.0 : (placement / distance));
}
You can calculate this value depending on which delta value is bigger. Delta between x
values of known points or delta between y
values.
Part of code:
// ...
double percentage;
if (delta.x > delta.y)
percentage = percent(start.x, end.x, current.x);
else
percentage = percent(start.y, end.y, current.y);
// ...
Then for creating each light (Red, Green, Blue) we need to get light from start and end point and use linear interpolation. At the end we need to get new color by union red, green and blue light.
Part of code:
// ...
int red;
int green;
int blue;
// Get percentage
red = get_light((start.color >> 16) & 0xFF, (end.color >> 16) & 0xFF, percentage);
green = get_light((start.color >> 8) & 0xFF, (end.color >> 8) & 0xFF, percentage);
blue = get_light(start.color & 0xFF, end.color & 0xFF, percentage);
return ((red << 16) | (green << 8) | blue);
int get_light(int start, int end, double percentage)
{
return ((int)((1 - percentage) * start + percentage * end));
}
Complete code:
int get_light(int start, int end, double percentage)
{
return ((int)((1 - percentage) * start + percentage * end));
}
int get_color(t_point current, t_point start, t_point end, t_point delta)
{
int red;
int green;
int blue;
double percentage;
if (current.color == end.color)
return (current.color);
if (delta.x > delta.y)
percentage = percent(start.x, end.x, current.x);
else
percentage = percent(start.y, end.y, current.y);
red = get_light((start.color >> 16) & 0xFF, (end.color >> 16) & 0xFF, percentage);
green = get_light((start.color >> 8) & 0xFF, (end.color >> 8) & 0xFF, percentage);
blue = get_light(start.color & 0xFF, end.color & 0xFF, percentage);
return ((red << 16) | (green << 8) | blue);
}
Basic information was found here.
On macOS
endian
value is useless and bits_per_pixel
value is constant. You can find the following lines in source files of minilibx:
/*
** endian : 0 = sever X is little endian, 1 = big endian
** endian : useless on macos, client and graphical framework have the same endian
*/
#define UNIQ_BPP 4
// assume here 32bpp little endian
char *mlx_get_data_addr(mlx_img_list_t *img_ptr, int *bits_per_pixel, int *size_line, int *endian)
{
*bits_per_pixel = UNIQ_BPP * 8;
*size_line = img_ptr->width * UNIQ_BPP;
*endian = 0; // little endian for now on mac-intel
return (img_ptr->buffer);
}
So order of lights in your code must be exactly RGB (If you decided to support only macOS
).
Structure of color looks like:
0 | R | G | B |
---|---|---|---|
8 bits | 8 bits | 8 bits | 8 bits |
You can find this information in mlx_pixel_put
man file.
The number of bits used to define a pixel's color shade is its bit-depth. True color is sometimes known as 24-bit color. Some new color display systems offer a 32-bit color mode. The extra byte, called the alpha channel, is used for control and special effects information.