硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2992|回复: 8
收起左侧

[emWin] emWin新增的炫酷光影例子,效果可以媲美当年TouchGFX的光影效果

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115778
QQ
发表于 2019-7-23 09:42:21 | 显示全部楼层 |阅读模式
例子:
GUI_NormalMapping_800x480.rar (669.11 KB, 下载次数: 54)

效果:
1.gif
回复

使用道具 举报

36

主题

2050

回帖

2158

积分

至尊会员

积分
2158
发表于 2019-7-23 10:07:39 | 显示全部楼层
看了下代码,是这么实现的:

  1. static int ShadeImage16(GUI_MAPPING_CONTEXT * pContext, int xPosLight, int yPosLight) {
  2.   U16      * pBmData;
  3.   int        Offset;
  4.   U8         CLight;
  5.   U8         r, g, b;
  6.   U16        Color;
  7.   U16      * pNMap;
  8.   U16      * pData;
  9.   const U8 * pLight;
  10.   U32        LightHalf;
  11.   int        y;
  12.   int        x;
  13.   int        xSizeLight;
  14.   int        ySizeLight;
  15.   GUI_RECT   Rect;
  16.   int        NoLight;

  17.   //
  18.   // Set up variables
  19.   //
  20.   pData = (U16 *)GUI_MEMDEV_GetDataPtr(pContext->hMemDest);
  21.   if (pData == NULL) {
  22.     return 1;
  23.   }
  24.   if (pContext->pBmImage) {
  25.     pBmData = (U16 *)pContext->pBmImage->pData;
  26.   } else {
  27.     pBmData = (U16 *)GUI_MEMDEV_GetDataPtr(pContext->hMemImage);
  28.     if (pBmData == NULL) {
  29.       return 1;
  30.     }
  31.   }
  32.   if (pContext->pbmLight) {
  33.     pLight     = (const U8 *)pContext->pbmLight->pData;
  34.     xSizeLight = pContext->pbmLight->XSize;
  35.     ySizeLight = pContext->pbmLight->YSize;
  36.     NoLight    = 0;
  37.   } else {
  38.     pLight     = NULL;
  39.     xSizeLight = 0;
  40.     ySizeLight = 0;
  41.     NoLight    = 1;
  42.   }
  43.   LightHalf = LIGHT_MAX >> 1;
  44.   Offset    = 0;
  45.   //
  46.   // Wihtout light the rectangle has the size of the image
  47.   //
  48.   if (NoLight) {
  49.     Rect.x0 = 0;
  50.     Rect.y0 = 0;
  51.     Rect.x1 = pContext->xSize;
  52.     Rect.y1 = pContext->ySize;
  53.   } else {
  54.     //
  55.     // With light only the light area needs to be touched
  56.     //
  57.     _CalcRect(&Rect, pContext, xPosLight, yPosLight);
  58.   }
  59.   //
  60.   // Itterate over the image
  61.   //
  62.   for (y = 0; y < pContext->ySize; y++) {
  63.     for (x = 0; x < pContext->xSize; x += 1, Offset += 1) {
  64.       //
  65.       // Get pixel data from the normal map and the image to be shaded
  66.       //
  67.       pNMap = ((U16 *)pContext->pNMap) + Offset;
  68.       Color = *(pBmData + Offset);
  69.       CLight = _GetLightCoefficient(NoLight, Rect, x, y, pNMap, pLight, xPosLight, yPosLight, xSizeLight, ySizeLight);
  70.       //
  71.       // Grap the colors from the current pixel
  72.       //
  73.       r = (Color & 0xF800) >> 11;
  74.       g = (Color & 0x07E0) >> 5;
  75.       b =  Color & 0x001F;
  76.       //
  77.       // Apply coefficient
  78.       //
  79.       if (CLight == 0) {
  80.         //
  81.         // No light, darken pixel
  82.         //
  83.         r = (r >> 2);
  84.         g = (g >> 2);
  85.         b = (b >> 2);
  86.       } else if ((U32)CLight <= LightHalf) {
  87.         //
  88.         // Apply a bit of light to pixels which are outside half of hte light radius
  89.         //
  90.         r = (r >> 2) + ((r - (r >> 2)) * CLight) / LightHalf;
  91.         g = (g >> 2) + ((g - (g >> 2)) * CLight) / LightHalf;
  92.         b = (b >> 2) + ((b - (b >> 2)) * CLight) / LightHalf;
  93.       } else {
  94.         //
  95.         // Apply light to those within range
  96.         //
  97.         r = r + (((0x1F ^ r) * (CLight - LightHalf)) / LightHalf);
  98.         g = g + (((0x3F ^ g) * (CLight - LightHalf)) / LightHalf);
  99.         b = b + (((0x1F ^ b) * (CLight - LightHalf)) / LightHalf);
  100.       }
  101.       //
  102.       // Shift colors bytes into order
  103.       //
  104.       Color = (r << 11) | (g << 5) | b;
  105.       //
  106.       // And write the pixel
  107.       //
  108.       *(pData + y * pContext->xSize + x) = Color;
  109.     }
  110.   }
  111.   return 0;
  112. }
复制代码


Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

8

主题

33

回帖

57

积分

初级会员

积分
57
发表于 2019-7-23 12:27:01 | 显示全部楼层
这个用rgba8888 然后用simd的话 速度可以快一倍不止
回复

使用道具 举报

42

主题

1022

回帖

1153

积分

至尊会员

积分
1153
发表于 2019-7-23 13:50:54 | 显示全部楼层
效果不错,但好像有些卡顿,没那么流畅
回复

使用道具 举报

9

主题

59

回帖

86

积分

初级会员

积分
86
发表于 2019-7-23 14:48:31 | 显示全部楼层
虽然没什么卵用,但是看起来还是挺酷的。。
最近在努力啃官方的例程,收获很多。。。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2019-7-24 11:19:36 | 显示全部楼层
试试。。。。。。。。。。
回复

使用道具 举报

2

主题

569

回帖

575

积分

金牌会员

积分
575
发表于 2019-7-24 17:46:29 | 显示全部楼层
用手电筒照亮你的美....
回复

使用道具 举报

23

主题

1443

回帖

1512

积分

至尊会员

积分
1512
发表于 2019-7-25 11:25:54 | 显示全部楼层
效果真不错
代码不规范,亲人两行泪!
回复

使用道具 举报

29

主题

514

回帖

606

积分

金牌会员

积分
606
QQ
发表于 2019-7-29 10:05:14 | 显示全部楼层
chenlijian80 发表于 2019-7-23 14:48
虽然没什么卵用,但是看起来还是挺酷的。。
最近在努力啃官方的例程,收获很多。。。

好事多磨,啃官网的例程,前期进步挺快的。然后自己改装例程,改bug的时候印象会更深刻
Releasing your creativity
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-18 05:24 , Processed in 0.302861 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表