cancel
Showing results for 
Search instead for 
Did you mean: 

Draw transparent rectangles

brbrr
Associate II

Hi there. I'm trying to figure out how to draw/fill rectangle with transparency. I can fill opaque rectangles without issues. 
I am using `stm32h750`, 320x240 ILI9341 LCD which supports RGB565 buffers. Below is the code that kinda works, but it generates weird colors. In that code, I'm using DMA2D_M2M_BLEND_FG with RGB565 color and I'm setting alpha for the rectangle in the foreground layer.  How can I make it work? 


```

hdma2d.Instance = DMA2D;
hdma2d.Init.Mode = DMA2D_M2M_BLEND_FG;
hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565;
hdma2d.Init.AlphaInverted = DMA2D_REGULAR_ALPHA;
hdma2d.Init.RedBlueSwap = DMA2D_RB_REGULAR;
hdma2d.Init.OutputOffset = screen_width - rect.GetWidth();
// Foreground
hdma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
hdma2d.LayerCfg[1].InputOffset = 0;
hdma2d.LayerCfg[1].InputAlpha = alpha;
hdma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR;
hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;

// Background
hdma2d.LayerCfg[0].InputAlpha = 0xff;
hdma2d.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA;
hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
hdma2d.LayerCfg[0].InputOffset = screen_width - rect.GetWidth();
hdma2d.LayerCfg[0].RedBlueSwap = DMA2D_RB_REGULAR;
hdma2d.LayerCfg[0].AlphaInverted = DMA2D_REGULAR_ALPHA;
HAL_DMA2D_Init(&hdma2d);
HAL_DMA2D_ConfigLayer(&hdma2d, 1);
HAL_DMA2D_ConfigLayer(&hdma2d, 0);

HAL_DMA2D_BlendingStart(&hdma2d,
color,
(uint32_t)(buffer + offset),
(uint32_t)(buffer + offset),
rect.GetWidth(),
rect.GetHeight());
```
7 REPLIES 7
Osman SOYKURT
ST Employee

Hello @brbrr ,

I have some doubts concerning your configuration. Transparency should be used with ARGB888 color.

OsmanSOYKURT_0-1696944566557.png

Can you check that and tell us if it helps?

Osman SOYKURT
ST Software Developer | TouchGFX
brbrr
Associate II

Thanks, I did try to use ARGB8888 for BLEND_FG, but unfortunately, I end up with completely messed up colors. For example:
- white (BG) + green@50alpha I end up with blue color
- gray + green@50alpha I'm getting purple 

Below is the updated configuration I am using (note I am converting RGB565 to ARGB8888):

 
uint32_t clr = RGB565toARGB8888(__builtin_bswap16(color), 0);
hdma2d.Instance = DMA2D;
hdma2d.Init.Mode = DMA2D_M2M_BLEND_FG;
hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565;
hdma2d.Init.AlphaInverted = DMA2D_REGULAR_ALPHA;
hdma2d.Init.RedBlueSwap = DMA2D_RB_REGULAR;
hdma2d.Init.OutputOffset = screen_width - rect.GetWidth();
// Foreground
hdma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
hdma2d.LayerCfg[1].InputOffset = 0;
hdma2d.LayerCfg[1].InputAlpha = alpha;
hdma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR;
hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;
 
 



Hello @brbrr ,

Did you succeed in resolving your issue?

Osman SOYKURT
ST Software Developer | TouchGFX

No, unfortunately. 

Have you checked in memory if your color is correct? If it is correct, then it's a display issue.

Osman SOYKURT
ST Software Developer | TouchGFX

Maybe your idea isnt real on used interface. How you drive LCD ILI9341? SPI? 

HW alpha blending and layers is designed to use only with LTDC and hw result color mix based on global and layers pixels.

Yeah, I'm using SPI for communicating with LCD. 

FWIW, HAL functions doesn't work nicely even for drawing opaque rects. I'm using a register-based approach (note

__builtin_bswap16 call on RGB565 color)

:

        MODIFY_REG(hdma2d.Instance->CR, DMA2D_CR_MODE, DMA2D_R2M);
        WRITE_REG(hdma2d.Instance->OCOLR, __builtin_bswap16(color));

        auto offset = (rect.GetX() + rect.GetY() * screen_width) * 2;

        MODIFY_REG(hdma2d.Instance->OOR, DMA2D_OOR_LO, 320 - rect.GetWidth());
        MODIFY_REG(
            hdma2d.Instance->NLR,
            (DMA2D_NLR_NL | DMA2D_NLR_PL),
            (rect.GetHeight() | (rect.GetWidth() << DMA2D_POSITION_NLR_PL)));
        WRITE_REG(hdma2d.Instance->OMAR, (uint32_t)(buffer + offset));
        hdma2d.Instance->CR |= DMA2D_CR_START