1、半透明原理: 假设 LCD 是 256 色的。颜色格式为 332(RGB) 显存中的每一个字节的数据对应一个象素点。 在数据写入显存之前,读取相应相素点值,然后与新的数据按一定的规则混合之后,再写入相应像素点的显存。这样主要问题关键是混合算法。 混合算法目前在游戏上常用到的算法是 AlphaBlend。计算公式如下 假设一幅图象是 A,另一幅透明的图象是 B,那么透过 B 去看 A,看上去的图象 C 就是 B 和 A 的混合图象,设 B 图象的透明度为 alpha(取值为 0-1,1 为完全透明,0 为完全不透明),Alpha 混合公式如下:R(C)=(1-alpha)*R(B)+alpha*
2、R(A)G(C)=(1-alpha)*G(B)+alpha*G(A)B(C)=(1-alpha)*B(B)+alpha*B(A)R(x)、G(x)、B(x)分别指颜色 x 的 RGB 分量原色值。从上面的公式可以知道,Alpha其实是一个决定混合透明度的数值。应用 Alpha 混合技术,可以实现游戏中的许多特效,比如火光、烟雾、阴影、动态光源等半透明效果。uC/GUI 系统分为好几个层面。简单地可以归结为:1、硬件驱动层2、基本 2D 图形库3、窗体层次越高,涉及的内容越多,修改的工作量就越大。 如果想修改最少的代码实现半透明功能,最好在硬件驱动层找切入口。在硬件驱动层中有个宏定义 LCD_W
3、RITE_MEM(Off,data) *(U8*)(DC+(U32)(Off)=(data ) ,从文档可以看到该宏定义的功能就是向显存写入像素点的值。流程如下:a、读取相应象素点值b、与新的象素点值按照混合算法转换。c、将转换结果写入显存对应位置。/设置透明度为 0,完全不透明,先执行清屏。GUI_SetBkColor(GUI_WHITE);GUI_SetColor(GUI_WHITE);GUI_Clear();/填充一个方框GUI_SetColor(GUI_RED);GUI_FillRect(0,0,80,30);*这里设置透明度为 80 透明之后再执行GUI_SetColor(GUI_G
4、REEN);GUI_FillRect(50,5,200,30);GUI_CONTEXTtypedef struct /* Variables in LCD module */LCD_COLORINDEX_UNION LCD;LCD_RECT ClipRect;U8 DrawMode;U8 SelLayer;U8 TextStyle;U8 TransPara;/* Variables in GL module */GUI_RECT* pClipRect_HL; /* High level clip rectangle . Speed optimization so drawing routine
5、s can optimize */U8 PenSize;U8 PenShape;U8 LineStyle;U8 FillStyle;/* Variables in GUICHAR module */const GUI_FONT GUI_UNI_PTR * pAFont;const GUI_UC_ENC_APILIST * pUC_API; /* Unicode encoding API */I16P LBorder;I16P DispPosX, DispPosY;I16P DrawPosX, DrawPosY;I16P TextMode, TextAlign;GUI_COLOR Color,
6、BkColor; /* Required only when changing devices and for speed opt (caching) */* Variables in WM module */#if GUI_WINSUPPORTconst GUI_RECT* WM_pUserClipRect;GUI_HWIN hAWin;int xOff, yOff;#endif/* Variables in MEMDEV module (with memory devices only) */#if GUI_SUPPORT_DEVICESconst tLCDDEV_APIList* pDe
7、viceAPI; /* function pointers only */GUI_HMEM hDevData;GUI_RECT ClipRectPrev;#endif/* Variables in Anitaliasing module */#if GUI_SUPPORT_AAconst tLCD_HL_APIList* pLCD_HL; /* Required to reroute drawing (HLine U8 AA_HiResEnable;#endif GUI_CONTEXT; 包含了整个系统作图的最基本信息。而且这个结构体所声明的变量GUI_Context 也是硬件作图层(硬件驱动
8、层) 所唯一依赖的变量。在结构体中发现,需要增加透明度信息。 于是在结构体中增加一条:U8 BlendPara;/混合算法参数 Alpha;现在来一个情景分析。1、在画图前设置该变量值。0-100 之间。2、在 LCD_WRITE_MEM 时使用它。这样半透明和透明效果就都实现了。用 2D 图形库作图测试确实能实现半透明效果。再测试窗体时你会发现一个问题。在基于 WM_Window 的所有控件上使作半透明效果会出现问题:在反复刷新(即反复产生 WM_PAINT)消息时,该窗体的颜色一直在变量,而且由浅及深或由深及浅反复变化实现 AlphaBlend 混合的代码.主要的算法是:r = (BYTE
9、)(rForeground - rBackground)*delta) ALPHA) + rBackground);g = (BYTE)(gForeground - gBackground)*delta) ALPHA) + gBackground);b = (BYTE)(bForeground - bBackground)*delta) ALPHA) + bBackground);下面是具体实现。(代码可成功运行 )/ 一共 28 + 1 个等级,0 为透明,256 为不透明,中间的值为半透明#define ALPHA 8#define FRAMEPENWIDTH 2 / 文本框的宽度#def
10、ine FRAMECOLOR RGB(192,192,192) / 文本框的颜色#define SHADOWWIDTH 1 / 阴影的宽度(为了有立体感)#define SHADOWCOLOR RGB(0,0,0) / 阴影的颜色#define TEXTCOLOR RGB(0,0,192) / 文本的颜色/ 文本框的宽度缺省 100 像素,宽度、高度可以动态调整#define DEFAULTOUTPUTWIDTH 100VOID ShowTransparentText(HWND hDstWnd, / 在那个窗口透明显示DWORD Alpha, / Alpha 通道值 (0 ALPHA) + r
11、Background);g = (BYTE)(gForeground - gBackground)*delta) ALPHA) + gBackground);b = (BYTE)(bForeground - bBackground)*delta) ALPHA) + bBackground);SetPixel(hWorkDC, x, y, RGB(r,g,b);/ 由于 Smartphone 不提供 FrameRect 函数,所以自行实现该功能。/ 画出外框for(y = 0; y/还要在 Project - setting - link 里连接上 msimg32.lib/VC 用 AlphaB
12、lend 实现半透明位图Requirements:Windows NT/2000/XP: Included in Windows 2000 and later.Windows 95/98/Me: Included in Windows 98 and later.Header: Declared in Wingdi.h; include Windows.h.Library: Included as a resource in Msimg32.dll.示例: 1. void CTestDlg:SaveBitmap(CDC* pDC,CRect rect,CString filename)2. 3.
13、 CDC* memDC=new CDC;4. memDC-CreateCompatibleDC(pDC);5. CBitmap* bmp=new CBitmap;6. bmp-CreateCompatibleBitmap(pDC,rect.Width(),rect.Height();7. CBitmap* oldbitmap=memDC-SelectObject(bmp);8. /此时的 bmp 就相当于一张桌布,在 memDC 中画线 etc 都是画在这张桌布上9. if(!memDC-BitBlt(0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY
14、)10. 11. AfxMessageBox(“BitBlt Error!“);12. return;13. 14. memDC-Ellipse(0,0,100,100);15. memDC-SelectObject(oldbitmap);16.17. BITMAPINFO bi;18. bi.bmiHeader.biSize=sizeof(bi.bmiHeader);19. bi.bmiHeader.biWidth=rect.Width();20. bi.bmiHeader.biHeight=rect.Height();21. bi.bmiHeader.biPlanes=1;22. bi.b
15、miHeader.biBitCount=16;23. bi.bmiHeader.biCompression=BI_RGB;24. bi.bmiHeader.biSizeImage=0;25. bi.bmiHeader.biXPelsPerMeter=0;26. bi.bmiHeader.biYPelsPerMeter=0;27. bi.bmiHeader.biClrUsed=0;28. bi.bmiHeader.biClrImportant=0;29.30. int bitsize=rect.Width()*rect.Height()*2;31. BYTE* bits=new BYTEbits
16、ize;32. :GetDIBits(memDC-m_hDC,*bmp,0,rect.Height(),bits,33. 34. BITMAPFILEHEADER bf;35. bf.bfType=(int)M*256+B;36. bf.bfSize=bitsize;/sizeof(bf);37. bf.bfOffBits=sizeof(bi.bmiHeader)+sizeof(bf);38. bf.bfReserved1=0;39. bf.bfReserved2=0;40.41. CFile f(filename,CFile:modeCreate|CFile:modeWrite);42. f
17、.Write(/注意是先写 bf,再写 bi43. f.Write(44. f.Write(bits,bitsize);45. f.Close();46.47. delete bits;48. delete bmp;49. delete memDC;50. 将 memDC 上的位图半透明覆盖到 pDC 上 1. BLENDFUNCTION bm;2. bm.BlendOp=AC_SRC_OVER;3. bm.BlendFlags=0;4. bm.SourceConstantAlpha=100;5. bm.AlphaFormat=0;6. AlphaBlend(pDC-m_hDC,0,0,rect.Width(),rect.Height(),memDC-m_hDC,0,0,rect.Width(),rect.Height(),bm);
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。