计算机屏幕是平面二维的,我们之所以能欣赏到真如实物般的三维图像,是因为显示在计算机屏幕上时色彩灰度的不同而使人眼产生视觉上的错觉,而将二维的计算机屏幕感知为三维图像。基于色彩学的有关知识,三维物体边缘的凸出部分一般显高亮度色,而凹下去的部分由于受光线的遮挡而显暗色。这一认识被广泛应用于网页或其他应用中对按钮、3D线条的绘制。对于本文所要绘制的3D文字同样也适用,即在原始位置显示高亮度颜色,而在左下或右上等位置用低亮度颜色勾勒出其轮廓,这样在视觉上便会产生3D文字的效果。具体实现时,可用完全一样的字体在不同的位置分别绘制两个不同颜色的2D文字,只要使两个文字的坐标合适,就完全可以在视觉上产生出不同效果的3D文字。
下面给出两种类似的实现方法并比较两者的效果:
void CMyDrawView::OnDraw(CDC* pDC)


{
CMyDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect rect1,rect2;
this->GetClientRect(&rect1);
rect2 = rect1+CPoint(80,80);
this->Draw3DText("欢迎使用",&rect1,44,0,FW_BOLD,0,"楷体_GB2312",pDC);
this->Draw3DText("欢迎使用",&rect2,pDC);
}
void CMyDrawView::Draw3DText(CString str,CRect rectText,int nHeight,int nWidth,int nWeight,BYTE bItalic,LPCTSTR lpszFacename,CDC *pDC)


{//画3D文字
CFont newFont,*oldFont;
COLORREF oldcolor;
newFont.CreateFont(nHeight,nWidth,0,0,nWeight,bItalic,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
FIXED_PITCH | FF_ROMAN,lpszFacename);//创建新字体
pDC->SetBkMode(TRANSPARENT);
oldFont = pDC->SelectObject(&newFont);//选进DC中
oldcolor = pDC->SetTextColor(RGB(0,0,0));
pDC->DrawText(str,rectText+CPoint(1,1),DT_SINGLELINE | DT_LEFT | DT_VCENTER|DT_CENTER);
pDC->SetTextColor(::GetSysColor(COLOR_BTNFACE));
pDC->DrawText(str,rectText,DT_SINGLELINE | DT_LEFT | DT_VCENTER|DT_CENTER);
pDC->SetTextColor(oldcolor);
pDC->SelectObject(oldFont);
}

void CMyDrawView::Draw3DText(CString str,CRect rect,CDC *pDC)


{
CFont newFont,*oldFont;
COLORREF oldColor;
LOGFONT f;
f.lfCharSet = DEFAULT_CHARSET;
f.lfClipPrecision = CLIP_DEFAULT_PRECIS;
f.lfEscapement = 0;
f.lfHeight = 44;
f.lfItalic = 0;
f.lfOrientation = 0;
f.lfOutPrecision = OUT_DEFAULT_PRECIS;
f.lfPitchAndFamily = FIXED_PITCH | FF_ROMAN;
f.lfQuality = DEFAULT_QUALITY;
f.lfStrikeOut = FALSE;
f.lfUnderline = FALSE;
f.lfWeight = FW_BOLD;
f.lfWidth = 0;
strcpy(f.lfFaceName,"楷体_GB2312");
newFont.CreateFontIndirect(&f);
oldColor = pDC->SetTextColor(RGB(0,0,0));
oldFont = (CFont*)pDC->SelectObject(&newFont);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(::GetSysColor(COLOR_3DDKSHADOW));
pDC->DrawText(str,rect,DT_SINGLELINE | DT_LEFT | DT_VCENTER|DT_CENTER);
pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
pDC->DrawText(str,rect+CPoint(1,1),DT_SINGLELINE | DT_LEFT | DT_VCENTER|DT_CENTER);
pDC->SelectObject(oldFont);
pDC->SetTextColor(oldColor);
}

对比效果如图所示:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述