eric2013 发表于 2020-7-24 09:01:48

LTDC背景层,图层1,图层2和Alpha混合

LTDC除了图层1和图层2两个硬件图层以外,还有一个背景层。由于背景层的刷新不需要显存空间,所以可以用这个图层验证LTDC时序配置是否有问题。




对于背景层来说,仅支持单色设置,固定颜色格式RGB888
hltdc_F.Init.Backcolor.Blue = 0
hltdc_F.Init.Backcolor.Green = 0
hltdc_F.Init.Backcolor.Red = 0

对于图层1和图层2来说,支持如下8种颜色格式:
– ARGB8888
– RGB888
– RGB565
– ARGB1555
– ARGB4444
– L8(8 位 Luminance 或 CLUT)
– AL44(4 位 alpha + 4 位 luminance)
– AL88(8 位 alpha + 8 位 luminance)
实现Alpha混合的关键是要有一个变量可以设置各种透明度。对此,STM32F429准备了两个Alpha供使用:
一个是常数Alpha(0x00表示完全透明,0xFF表示完全不透明),所有颜色格式都可以使用。
另一个是像素Alpha,也就是ARGB8888,ARGB1555,ARGB4444等颜色格式的Alpha通道数值,也就是我们为图层每个位置绘制的实际颜色值。

static/image/hrline/4.gif

了解了这点后就是具体的实现了。STM32F429的参考手册给出了具体的混合公式

BC          =BF1       x   C   +   BF2      x    Cs
混合后的颜色= 混合系数1 x 当前层颜色 + 混合系数2 x 底层混合后的颜色
混合系数1可以选择:
(1)常数 Alpha
(2)像素 Alpha x 常数 Alpha

混合系数2可以选择:
(1)1 - 常数 Alpha
(2)1 - 像素 Alpha x 常数 Alpha

底层混合后的颜色:
(1)可以是背景层。
(2)可以是背景层与图层1混合后的颜色。

那么公式就变成如下形式(主要是如下两种):
混合后的颜色 = 常数 Alpha x 当前层颜色 + (1 - 常数 Alpha) x 底层混合后的颜色。
混合后的颜色 = 像素 Alpha x 常数 Alpha x 当前层颜色 +
(1 - 像素 Alpha x 常数 Alpha) x 底层混合后的颜色。

再进一步简化,代入HAL库参数(LTDC_LayerCfgTypeDefpLayerCfg):
像素Alpha是ARGB8888,ARGB1555等颜色格式的Alpha数值,也就是我们为图层每个位置绘制的实际颜色值,我们这里用AlphaValue表示。
混合后的颜色 = (pLayerCfg.Alpha /255 ) x 当前层颜色 +
(1 - pLayerCfg.Alpha /255 ) x 底层混合后的颜色。
混合后的颜色 = (AlphaValue/255)x (pLayerCfg.Alpha /255 ) x 当前层颜色 +
(1 - (AlphaValue/255)x (pLayerCfg.Alpha /255 )) x 底层混合后的颜色。

注,Alpha值要做归一化,Alpha的范围是0 - 255,比如Alpha = 100,那么代入公式的时候就是100/255。

举例:
(1)混合因数1选择像素 Alpha x 常数 Alpha。
(2)混合因数2选择像素 Alpha x 常数 Alpha。
(3)使用图层1和背景层,图层1使用ARGB8888颜色格式。
(4)背景色 = 0xFF0000,图层1位置坐标(0,0)颜色值0x5500FF00。
(5)Alpha常数 = 0x77
混合后的颜色 = (AlphaValue/255)x (pLayerCfg.Alpha /255 ) x 当前层颜色 +
(1 - (AlphaValue/255)x (pLayerCfg.Alpha /255 )) x 底层混合后的颜色。
             = (0x55/255)x (0x77/255) x 0x00FF00 +
(1 - (0x55/255)x (0x77/255)) x 0xFF0000
             =0xD7809C

最后注意一点:
如果大家设置的图层显示区没有显示满整个显示屏,且使用的ARGB颜色格式,那么未覆盖的区域会使用图层默认颜色。对此HAL库有专门的配置:
LTDC_LayerCfgTypeDef      pLayerCfg
pLayerCfg.Alpha0 = 0;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;

Bird 发表于 2020-9-23 22:06:51

请教Eric大哥,我在应用中发现部分灰色显示成了别的颜色,
然后用背景图层验证LTDC时序配置,设置背景色为
LTDC_Handler.Init.Backcolor.Red=45;         
LTDC_Handler.Init.Backcolor.Green=45;         
LTDC_Handler.Init.Backcolor.Blue=45;
深灰色,显示正常
改为以下值:
LTDC_Handler.Init.Backcolor.Red=73;         
LTDC_Handler.Init.Backcolor.Green=77;         
LTDC_Handler.Init.Backcolor.Blue=80;
显示的颜色就不对了,实际显示的颜色类似您配图背景层的颜色。
又做了几组实验RGB分别为(65,65,65), (80,80,80),(100, 100, 100)显示的都是跟(73,77,80)同样的颜色。

这样的情况是时序有问题吗,具体会是哪个参数引起的呢,奇怪的是灰色RGB似乎超过某组值就无法正常显示了。

廷润 发表于 2020-9-29 15:21:29

回想以前玩机顶盒UI,可以分背景层、静态层、视频层、OSD层、光标层。

yunqi 发表于 2023-1-16 16:58:58

廷润 发表于 2020-9-29 15:21
回想以前玩机顶盒UI,可以分背景层、静态层、视频层、OSD层、光标层。

说白了,就是对应的像素点与或一下。只不过硬件处理了。
以前街机游戏的背景图也分的好几层,都是这么搞的

国产娃娃菜 发表于 2023-6-24 17:51:46

Bird 发表于 2020-9-23 22:06
请教Eric大哥,我在应用中发现部分灰色显示成了别的颜色,
然后用背景图层验证LTDC时序配置,设置背景色 ...

遇到同样问题了,请教大哥解决了吗

lsx 发表于 2023-9-24 10:19:03

国产娃娃菜 发表于 2023-6-24 17:51
遇到同样问题了,请教大哥解决了吗

背景层只能设置单色
页: [1]
查看完整版本: LTDC背景层,图层1,图层2和Alpha混合