I'm taking my first steps in C, and was trying to make a gradient color function, that draws a bunch of rectangles to the screen (vertically). This is the code so far:
void draw_gradient(uint32_t start_color, uint32_t end_color) {
int steps = 8;
int draw_height = window_height / 8;
//Change this value inside the loop to write different color
uint32_t loop_color = start_color;
for (int i = 0; i < steps; i ) {
draw_rect(0, i * draw_height, window_width, draw_height, loop_color);
}
}
Ignoring the end_color
for now, I want to try and pass a simple red color in like 0xFFFF0000
(ARGB)..and then take the red 'FF' and convert it to an integer or decrease it using the loop_color
variable.
I'm not sure how to go get the red value from the hexcode and then minipulate it as a number and then write it back to hex..any ideas?
So in 8 steps the code should for example go in hex from FF
to 00
or as integer from 255
to 0
.
CodePudding user response:
As you have said, your color is in RGB format. This calculation assumes vertical gradient - meaning from top to the bottom (linear lines).
Steps to do are:
- Get number of lines to draw; this is your rectangle height
- Get A, R, G, B color components from your start and end colors
uint8_t start_a = start_color >> 24;
uint8_t start_r = start_color >> 16;
uint8_t start_r = start_color >> 8;
uint8_t start_r = start_color >> 0;
uint8_t end_a = end_color >> 24;
uint8_t end_r = end_color >> 16;
uint8_t end_r = end_color >> 8;
uint8_t end_r = end_color >> 0;
- Calculate step for each of the components
float step_a = (float)(end_a - start_a) / (float)height;
float step_r = (float)(end_r - start_r) / (float)height;
float step_g = (float)(end_g - start_g) / (float)height;
float step_b = (float)(end_b - start_b) / (float)height;
- Run for loop and apply different step for each color
for (int i = 0; i < height; i) {
uint32_t color = 0 |
((start_a i * step_a) & 0xFF) << 24 |
((start_r i * step_r) & 0xFF) << 16 |
((start_g i * step_g) & 0xFF) << 8 |
((start_b i * step_b) & 0xFF) << 0
draw_horizontal_line(i, color);
}
It is better to use float for step_x
and multiply/add on each iteration. Otherwise with integer rounding, you may never increase number as it will always get rounded down.