createpolygonrgn 所做的就是路径要做的。 例子如下 function Tform1.CreateRegion(wMask: TBitmap; wColor: TColor; hControl: THandle): HRGN; var dc, dc_c : HDC; rgn : HRGN; x, y : integer; coord : TPoint; line : boolean; color : TColor; begin dc := GetWindowDC(hControl); dc_c := CreateCompatibleDC(dc); {创建一个与特定设备场景一致的内存设备场景} SelectObject(dc_c, wMask.Handle); {把位图选入内存设备场景这样才可以操作!} BeginPath(dc); {启动一个路径分支。 在这个命令后执行的GDI绘图命令会自动成为路径的一部分。 对线段的连接会结合到一起。并且设备场景中任何现成的路径都会被清除。} for x := 0 to wMask.Width - 1 do begin line := false; for y := 0 to wMask.Height - 1 do begin color := GetPixel(dc_c, x, y); if not (color = wColor) then begin if not line then {如果这个不同颜色的线段开始了当然就不记录了!} begin line := true; {这是记录下这一列连续的不是背景颜色的颜色段的第一个位子。} coord.x := x; {其实这个X是不用的,因为coord.x是恒等于x的。但尊重源作者,保留!} coord.y := y; end; end; if (color = wColor) or (y = wMask.Height - 1) then {如果这个颜色段完了或者到了图片底部} begin if line then begin line := false; MoveToEx(dc, coord.x, coord.y, nil); {就把画线的起点移到这个列线段不同颜色的开始} LineTo(dc, coord.x, y); LineTo(dc, coord.x + 1, y); LineTo(dc, coord.x + 1, coord.y); {上面三个LineTo()语句就是画一个2×y的矩形。 一定要这样才可以画上每个点!并且连在一起的如果你查查Win32 SDK手册你还可以用Rectangle(dc, coord.x, coord.y, x + 2, y)等其他的画图函数代替从MoveToEx()开始的四个语句!也是一样的,只要记住要把点画完而且要重叠地画才可以把路径连在一起!} CloseFigure(dc); {描绘到一个路径时,关闭当前打开的图形。万重大侠说不可以少,我不理解,但是多了不错。} end; end; end; end; EndPath(dc); {结束画路径} rgn := PathToRegion(dc); {连接路径为区域的函数。} ReleaseDC(hControl, dc); {释放资源,公式化的必须使用。} Result := rgn; end;//也许对你有用 //
你要说的用openGL函数有类似的灯光效果的
函数应用,
如果在delphi 中,图画程序就是使用
canvas,那里面也能实现阴影,
不过需要你自己写程序。
例如:
要画一个球的阴影,需要使用投影几何
计算出阴影投射范围(坐标)
然后,根据这个写一个给这个范围染色的
程序如果是矩形fillrect就好了。又如,一个不规则物体,投影可能是个规则
形状,也可能是个不规则形状,你还需
要用到路径......这里面的东西太多。
自己写很难,很麻烦的。
我有看过一个流程制图工具,实现阴影操作的,它就是选中相应的图形然后进行设置格式.先不说,出现阴影它的位置有很多种,只说,平常在右下角出现的阴影,有以下几个疑问:
1.是否需要先判断图形是什么样形状.
2.是不是要得到选中图形的坐标点或相应的高/宽(这里要考虑到如果我是选中多个图形呢)
3.是不是要在次绘画一个相应的形状,并填充上颜色.
(即阴影部分是不是根据偏移多少重画一个图形.)
4.那怎么决定它与选中图形的相差位置是多少.即向右下偏移多少.
如果是一个连接线那么在右下角就应该出现阴影,如果是矩形,那么左边的线段就不应该画出
阴影。这就是灯光了
2 需要坐标
用线段来说,阴影是附着在线段一边的(周围)
多个图形就不用管了,只要我们的刷子类型不是clear就能实现阴影重叠
3,4都是投影几何的问题
不过你想想看,如果灯光从一面照射过来,是不是所有的图形的阴影和他们
本身都一样?
除了用canvas,是否可以利用CreatePolygonRgn/CombineRgn/FillRgn这三个API函数达到阴影效果. 假设窗体上放置了几个按钮,对应矩形/椭圆/圆角型,我单击矩形画出矩形图形,实现阴影效果_,可以知道不管是什么图形所达阴影效果都是在原图形的基础上偏移,这是一个共同点.
所以,如何做可以综合这一点,写成函数.这是一个问题.
例子如下
function Tform1.CreateRegion(wMask: TBitmap; wColor: TColor; hControl: THandle): HRGN;
var
dc, dc_c : HDC;
rgn : HRGN;
x, y : integer;
coord : TPoint;
line : boolean;
color : TColor;
begin
dc := GetWindowDC(hControl);
dc_c := CreateCompatibleDC(dc);
{创建一个与特定设备场景一致的内存设备场景}
SelectObject(dc_c, wMask.Handle);
{把位图选入内存设备场景这样才可以操作!}
BeginPath(dc);
{启动一个路径分支。
在这个命令后执行的GDI绘图命令会自动成为路径的一部分。
对线段的连接会结合到一起。并且设备场景中任何现成的路径都会被清除。}
for x := 0 to wMask.Width - 1 do
begin
line := false;
for y := 0 to wMask.Height - 1 do
begin
color := GetPixel(dc_c, x, y);
if not (color = wColor) then
begin
if not line then
{如果这个不同颜色的线段开始了当然就不记录了!}
begin
line := true; {这是记录下这一列连续的不是背景颜色的颜色段的第一个位子。}
coord.x := x; {其实这个X是不用的,因为coord.x是恒等于x的。但尊重源作者,保留!}
coord.y := y;
end;
end;
if (color = wColor) or (y = wMask.Height - 1) then {如果这个颜色段完了或者到了图片底部}
begin
if line then
begin
line := false;
MoveToEx(dc, coord.x, coord.y, nil); {就把画线的起点移到这个列线段不同颜色的开始}
LineTo(dc, coord.x, y);
LineTo(dc, coord.x + 1, y);
LineTo(dc, coord.x + 1, coord.y); {上面三个LineTo()语句就是画一个2×y的矩形。
一定要这样才可以画上每个点!并且连在一起的如果你查查Win32 SDK手册你还可以用Rectangle(dc, coord.x, coord.y, x + 2, y)等其他的画图函数代替从MoveToEx()开始的四个语句!也是一样的,只要记住要把点画完而且要重叠地画才可以把路径连在一起!}
CloseFigure(dc); {描绘到一个路径时,关闭当前打开的图形。万重大侠说不可以少,我不理解,但是多了不错。}
end;
end;
end;
end;
EndPath(dc); {结束画路径}
rgn := PathToRegion(dc); {连接路径为区域的函数。}
ReleaseDC(hControl, dc); {释放资源,公式化的必须使用。}
Result := rgn;
end;//也许对你有用
//