Files
lib_rgb/lib_rgb/api/rgb_effect.h

169 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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