实现画出各种形状的图形(比如流程图中各种形状图)并含有阴影效果。采用画布,选择不同颜色来画出相应的形状并达到含有阴影的效果,但这并不完美。现在想通过运用FillRgn等相关API函数来实现如此效果,不知有谁懂得,请帮忙分析分析哦

解决方案 »

  1.   

    这里是delphi,不是openGL和D3D,
    你要说的用openGL函数有类似的灯光效果的
    函数应用,
    如果在delphi 中,图画程序就是使用
    canvas,那里面也能实现阴影,
    不过需要你自己写程序。
    例如:
    要画一个球的阴影,需要使用投影几何
    计算出阴影投射范围(坐标)
    然后,根据这个写一个给这个范围染色的
    程序如果是矩形fillrect就好了。又如,一个不规则物体,投影可能是个规则
    形状,也可能是个不规则形状,你还需
    要用到路径......这里面的东西太多。
    自己写很难,很麻烦的。
      

  2.   

    好像还真的很复杂哦!有这么遭糕.我是利用过canvas,根据设置不同颜色的刷子,画两次,达到有阴影效果.但这只是单方面的而已.如果我要运用到各种各样的形状就不行了.
     
      我有看过一个流程制图工具,实现阴影操作的,它就是选中相应的图形然后进行设置格式.先不说,出现阴影它的位置有很多种,只说,平常在右下角出现的阴影,有以下几个疑问:
    1.是否需要先判断图形是什么样形状.
    2.是不是要得到选中图形的坐标点或相应的高/宽(这里要考虑到如果我是选中多个图形呢)
    3.是不是要在次绘画一个相应的形状,并填充上颜色.
       (即阴影部分是不是根据偏移多少重画一个图形.)
    4.那怎么决定它与选中图形的相差位置是多少.即向右下偏移多少.
      

  3.   

    1 当然要判断形状
      如果是一个连接线那么在右下角就应该出现阴影,如果是矩形,那么左边的线段就不应该画出
    阴影。这就是灯光了
    2 需要坐标
      用线段来说,阴影是附着在线段一边的(周围)
      多个图形就不用管了,只要我们的刷子类型不是clear就能实现阴影重叠
    3,4都是投影几何的问题
     不过你想想看,如果灯光从一面照射过来,是不是所有的图形的阴影和他们
     本身都一样?
      

  4.   

    这个涉及得有点复杂..
    除了用canvas,是否可以利用CreatePolygonRgn/CombineRgn/FillRgn这三个API函数达到阴影效果. 假设窗体上放置了几个按钮,对应矩形/椭圆/圆角型,我单击矩形画出矩形图形,实现阴影效果_,可以知道不管是什么图形所达阴影效果都是在原图形的基础上偏移,这是一个共同点.
    所以,如何做可以综合这一点,写成函数.这是一个问题.
      

  5.   

    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;//也许对你有用
    //
      

  6.   

    你好,不知你对ExpressFlowChart这个控件了解不?