forked from PAWPAW/lib_rgb
169 lines
6.6 KiB
C
169 lines
6.6 KiB
C
#ifndef RGB_EFFECT_H
|
||
#define RGB_EFFECT_H
|
||
#include <stdint.h>
|
||
#include <stddef.h>
|
||
#include "rgb_driver.h"
|
||
#include "samples_to_levels.h"
|
||
#include "misc_utils.h"
|
||
|
||
// 在Makefile中定义编译选项,以使用xua配置项覆盖定义
|
||
#ifdef _XUA_CONF_H_EXISTS_
|
||
#include "xua_conf.h"
|
||
#endif
|
||
|
||
// RGB灯的数量
|
||
#ifndef NUM_RGBS
|
||
#define NUM_RGBS (12)
|
||
#endif
|
||
|
||
// RGB灯组的数量,不应超过NUM_RGBS
|
||
#ifndef NUM_RGB_GROUPS
|
||
#define NUM_RGB_GROUPS (2)
|
||
#endif
|
||
|
||
// 控制RGB亮度的最大值,不超过255
|
||
#ifndef RGB_MAX
|
||
#define RGB_MAX (20)
|
||
#endif
|
||
|
||
// TODO:优化为编译时检查?
|
||
// 开关饱和检查,该检查会引入性能损失,在需要高刷新率时关闭它
|
||
#ifndef HSV_VALID_CHECK
|
||
#define HSV_VALID_CHECK (1)
|
||
#endif
|
||
|
||
// 控制HUE的最大值,不超过360°
|
||
#ifndef HSV_HUE_MAX
|
||
#define HSV_HUE_MAX (360)
|
||
#endif
|
||
|
||
// 控制饱和度的最大值,不超过100
|
||
#ifndef HSV_SATURATION_MAX
|
||
#define HSV_SATURATION_MAX (100)
|
||
#endif
|
||
|
||
// 控制VALUE,不超过100
|
||
#ifndef HSV_VALUE_MAX
|
||
#define HSV_VALUE_MAX (100)
|
||
#endif
|
||
|
||
// 微秒,定义每次颜色更新的延迟,在cycleRGB下,
|
||
// (1000/RGB_MAX)代表每个B/R/G值的爬升/缓降时间约为1000ms
|
||
#ifndef DELAY_TIME_RGB
|
||
#define DELAY_TIME_RGB (1000 / RGB_MAX)
|
||
#endif
|
||
|
||
// 控制cycleHSV中,HUE递增的步进值,该步进值应能整除360,且不超过它
|
||
#ifndef HUE_STEP
|
||
#define HUE_STEP (1)
|
||
#endif
|
||
/**
|
||
* 定义渐变方向的枚举类型。
|
||
*
|
||
* 该枚举用于指定颜色渐变过程中亮度的变化方向,用于控制RGB颜色空间的遍历,
|
||
* 实现颜色的平滑过渡,如呼吸灯效果。
|
||
*/
|
||
typedef enum
|
||
{
|
||
INCREMENTING, ///< 亮度递增:用于指示颜色亮度逐渐增加的渐变方向。
|
||
DECREMENTING ///< 亮度递减:用于指示颜色亮度逐渐减少的渐变方向。
|
||
} GradientDirection;
|
||
|
||
|
||
/** 遍历RGB颜色空间以实现呼吸灯效果。
|
||
*
|
||
* 此函数通过逐步调整RGB值来模拟呼吸灯效果,根据提供的方向增加或减少颜色亮度。
|
||
* 它更新颜色值,并将新颜色值通过RGB条输出。
|
||
*
|
||
* \param buf 指向存储RGB值的缓冲区的指针。
|
||
* \param color 当前颜色值。
|
||
* \param direction 指向当前渐变方向的指针,可以是递增或递减。
|
||
* \return 更新后的颜色值。
|
||
*/
|
||
uint32_t cycleRGB(uint32_t color, GradientDirection *direction);
|
||
|
||
/**
|
||
* 通过HSV颜色空间循环改变色调(Hue)以实现颜色渐变效果。
|
||
*
|
||
* 此函数负责在HSV颜色模型中改变色调值,从而在不改变饱和度(Saturation)和亮度(Value)的情况下
|
||
* 遍历不同的颜色。色调值会在0到359之间循环,每次调用函数色调值增加1,当达到359后重置为0。
|
||
* 函数输出当前色调值并将新的RGB值存储在提供的缓冲区中。
|
||
*
|
||
* \param buf 指向存储RGB值的缓冲区的指针。此缓冲区将被更新为对应的RGB值。
|
||
* \param hue 指向当前色调值的指针。色调值在0到359之间变化。
|
||
*
|
||
* \return 根据当前色调值、饱和度和亮度计算出的RGB颜色值。
|
||
*/
|
||
uint32_t cycleHSV(uint32_t *hue);
|
||
|
||
/**
|
||
* 将HSV颜色空间转换为RGB颜色空间。
|
||
*
|
||
* 此函数接受HSV(色相、饱和度、亮度)颜色空间的值,并将其转换为RGB(红、绿、蓝)颜色空间的值。
|
||
* 转换过程中,可能会执行有效性检查(取决于HSV_VALID_CHECK预处理器变量)。
|
||
*
|
||
* 实现步骤:
|
||
* 1. **规范化色调值:**
|
||
* $ H' = \frac{H}{360} $
|
||
*
|
||
* 2. **计算色度(Chroma):**
|
||
* $ C = S \times V $
|
||
*
|
||
* 3. **计算X值:**
|
||
* $ X = C \times (1 - |(H' \times 6) \mod 2 - 1|) $
|
||
*
|
||
* 4. **计算中间RGB值:**
|
||
* 根据H'的值,我们有:
|
||
* - 如果 $( 0 \leq H' < 1 )$:$ R1 = C, G1 = X, B1 = 0 $
|
||
* - 如果 $( 1 \leq H' < 2 )$:$ R1 = X, G1 = C, B1 = 0 $
|
||
* - 如果 $( 2 \leq H' < 3 )$:$ R1 = 0, G1 = C, B1 = X $
|
||
* - 如果 $( 3 \leq H' < 4 )$:$ R1 = 0, G1 = X, B1 = C $
|
||
* - 如果 $( 4 \leq H' < 5 )$:$ R1 = X, G1 = 0, B1 = C $
|
||
* - 如果 $( 5 \leq H' < 6 )$:$ R1 = C, G1 = 0, B1 = X $
|
||
*
|
||
* 5. **计算最终RGB值:**
|
||
* $ R' = (R1 + (V - C)) \times 255 $
|
||
* $ G' = (G1 + (V - C)) \times 255 $
|
||
* $ B' = (B1 + (V - C)) \times 255 $
|
||
*
|
||
* 6. **限制最终值范围:**
|
||
* $ R'' = \min(\max(R', 0), 255) $
|
||
* $ G'' = \min(\max(G', 0), 255) $
|
||
* $ B'' = \min(\max(B', 0), 255) $
|
||
*
|
||
* \param hue 指向色相值的指针,色相值的范围通常是0-360。
|
||
* \param sat 指向饱和度值的指针,饱和度值的范围通常是0-100。
|
||
* \param value 指向亮度值的指针,亮度值的范围通常是0-100。
|
||
*
|
||
* \return 转换后的RGB值,其中G占最高8位,R占中间8位,B占最低8位。
|
||
*/
|
||
uint32_t HSV_to_RGB(uint32_t *hue, uint32_t *sat, uint32_t *value);
|
||
|
||
/**
|
||
* 将单一颜色填充到整个RGB条中,并控制显示颜色的时间长度。
|
||
*
|
||
* 此函数遍历RGB条的每个颜色单元,将它们统一设置为提供的颜色值。设置完成后,
|
||
* 通过调用输出函数将这些颜色输出到RGB条上。之后,函数会调用延迟函数以保持
|
||
* 当前颜色一段时间,从而控制颜色显示的持续时间,这可以用于创建闪烁效果。
|
||
*
|
||
* \param buf 指向存储RGB值的缓冲区的指针,每个元素代表RGB条中一个颜色单元的颜色值。
|
||
* \param color 要填充的统一颜色值。
|
||
*/
|
||
void fill_gradient(uint32_t *buf, uint32_t color, size_t num_filled_rgb);
|
||
|
||
/**
|
||
* 将多种颜色分组填充到RGB条中,并控制显示颜色的时间长度。
|
||
*
|
||
* 此函数将RGB条分为若干组,每组填充指定的颜色。每组可以填充不同数量的RGB单元,
|
||
* 数量由num_filled_rgb数组指定。填充完所有组指定的颜色后,剩余的RGB单元将被熄灭。
|
||
* 如果组号为奇数,则该组的颜色顺序将被翻转。所有颜色设置完成后,通过调用输出函数
|
||
* 将这些颜色输出到RGB条上。最后,函数调用延迟函数以保持当前颜色一段时间。
|
||
*
|
||
* \param buf 指向存储RGB值的缓冲区的指针,每个元素代表RGB条中一个颜色单元的颜色值。
|
||
* \param colors 指向存储每组颜色值的数组的指针,每个元素代表一个组的颜色值。
|
||
* \param num_filled_rgb 指向存储每组已填充RGB单元数量的数组的指针,每个元素代表一个组已填充的RGB单元数量。
|
||
*/
|
||
void fill_gradient_with_groups(uint32_t *buf, uint32_t *colors, size_t *num_filled_rgb);
|
||
|
||
void fill_gradient_with_groups_colorful(uint32_t *buf, uint32_t *colors, size_t *num_filled_rgb);
|
||
#endif //RGB_EFFECT_H
|