Timer_GetWave.Enabled:=false;
        timestart:=now();
        self.GroupBox_Draw.DoubleBuffered:=true;
        for i:=0 to 500 do
        begin
                getdata();
                drawdata();
           //     PB.Canvas.Draw(0,0,_DrawMap);
        end;
        timeend:=now();
        self.LabelFPS.Caption:=inttostr(milliSecondsBetween(timestart,timeend));-------------------------------------------------------------------------用了双缓冲,以上代码的执行结果是1100毫秒.如果我把PB.Canvas.Draw(0,0,_DrawMap);加上去,执行结果要9900毫秒,效率差了十倍.请问有什么方法可以加上这句后效率不变化那么大~?给个思路也好~~

解决方案 »

  1.   

    对于占用大量计算时间的画图操作不能使用直接在PictureBox上画图的办法的,这样效率很低的,好久不做这方面的程序了,具体方法我说不清楚,你自己查,给你个思路。
    第一步,计算需要的画图数据
    第二步,在内存页(一般是bitmap对象)画出图形(这两步花费比较长的时间)
    第三步,直接用显示组件(例如PictureBox)把画好的内存页直接调入,显示出来。
    根据需要使用内存页的数量。
    如果图形的计算与绘制本身就是要花很多时间,这个画图程序是没有办法降低画图时间的,但是使用上边的方法,可以消除绘画的过程(至少用户看不到),不会产生图形的闪烁。而且内存页的绘制时间本身也要比直接绘制显示还是要快。
      

  2.   

    好像要用到bitblt函数,如果组件不提供类似方法,就要用Windows API了。
      

  3.   

    我就是用TBitmap在内存画的啊~~然后发觉贴出来的时候,
     PB.Canvas.Draw(0,0,_DrawMap);
    特别耗时间~~~不执行 PB.Canvas.Draw(0,0,_DrawMap);的话比执行快很多~
      

  4.   

    显示本来就耗时间啊,需要从内存到显存复制,就是直接用BitBlt也快不了多少。
    如果不需要动画效果,全部画完之后再更新显示就可以了,否则单独用一个线程(定时器也可以)来更新,每秒更新个15-30次就够了,完全不需要象你现在这样每秒50几帧。
      

  5.   

    30FPS就是实时显示了。
    你非要50FPS以上,没啥意义。
      

  6.   

    for i:=0 to 500 do
            begin
                    getdata();
                    drawdata();
               //     PB.Canvas.Draw(0,0,_DrawMap);
            end;
    要求太高了,什么软件,如果真的是要求高效的制图,请使用DirectX,不要用原始方法。
      

  7.   

    DirectX~~~用不用装多什么开发工具~~~没用过~~~~能给个小例子看看吗~~?
      

  8.   

    要装DirectX开发包,例子我现在拿不出来,入门肯定也不容易,这个一般只有做3D游戏才需要,首先你弄清楚你的需求,不要乱来。
      

  9.   

    不知道你的具体需求,我只是讨论一下:
    1)如果你采样的数据是历史增量数据,只需要在上面更新新的数据,而不需要整幅图重画吧。也就是你的DRAWDATA应该直接向PB的CANVAS上画,我想,如果新数据量应该不会很大吧。
    2)如果新数据真的很大,就只能是使用DIRECTX了。
    3)如果如你的程序给出的思路,那么也可以在显示的时候将一组合并成一帧来画吧。
      

  10.   

    opengl 可以看 nehe 入门例子做简单 还是可以的
    另外teechart控件包有 封装 opengl chart
      

  11.   

    netfly(支点)说得对,可以考虑只重画变化了的部分,不用全部重画。
      

  12.   

    只是简单绘制2D图,用什么速度都差不多。并不是你用DirectX(准确地讲是用DirectX中的DirectDraw)或者OpenGL就能快多少。
    如果你是显示一个连续变化的波形(因为你有Timer_GetWave这种命名),那么可以使用ScrollDC把前一幅图卷动一下(左到右或者右到左之类的),然后画上更新的部分就可以了。
      

  13.   

    谢谢各位!现在问题解决了!说出来笑死人,郁闷了我好多天.....原来是给我用的那个笔记本电脑没显卡驱动
    ......我写的东西是用在工业超声探伤上的波形显示.procedure TForm1.Button1Click(Sender: TObject);
    var
            c1,t1,t2:int64;
            t3:double;
    begin
            self.Button1.Enabled:=false;
            QueryPerformanceFrequency(c1);
            DrawCount:=0;
            self.Button1.Enabled:=false;
            QueryPerformanceCounter(t1);
            while true do
            begin
                    GetPoints;
                    Draw;
                    DrawCount:=DrawCount+1;
                    Form1.Edit1.Text:=IntToStr(DrawCount);
                    Application.ProcessMessages;
                    if DrawCount=500 then
                    begin
                            break;
                    end;
            end;
            QueryPerformanceCounter(t2);
            t3:=(t2-t1)/c1*1000;
            ShowMessage('实际经过时间'+FloatToStr(t3)+'毫秒');
            self.Button1.Enabled:=true;
    end;
    //取得模拟数据
    procedure GetPoints;
    var
            x:integer;
    begin
    //取得数据
            for x:=0 to 511 do
            begin
                    DrawPoints[x].X:=x;
                    DrawPoints[x].Y:=random(300);
            end;
    end;
    //画图
    procedure Draw;
    begin
            //画背景入缓存
            Form1.Image1.Canvas.Brush.Color:=clBlack;
            Form1.Image1.Canvas.FillRect(Rect(0,0,512,300));
            //画波形入缓存
            Form1.Image1.Canvas.Pen.Style:=psSolid;
            Form1.Image1.Canvas.Pen.Color:=clGreen;
            Form1.Image1.Canvas.Polyline(DrawPoints);
            //画网格入缓存
            Form1.Image1.Canvas.Pen.Style:=psDot;
            Form1.Image1.Canvas.Pen.Color:=clRed;
            Form1.Image1.Canvas.MoveTo(0,30);
            Form1.Image1.Canvas.LineTo(511,30);
            Form1.Image1.Canvas.MoveTo(0,60);
            Form1.Image1.Canvas.LineTo(511,60);
            Form1.Image1.Canvas.MoveTo(0,90);
            Form1.Image1.Canvas.LineTo(511,90);
            Form1.Image1.Canvas.MoveTo(0,120);
            Form1.Image1.Canvas.LineTo(511,120);
            Form1.Image1.Canvas.MoveTo(0,150);
            Form1.Image1.Canvas.LineTo(511,150);
            Form1.Image1.Canvas.MoveTo(0,180);
            Form1.Image1.Canvas.LineTo(511,180);
            Form1.Image1.Canvas.MoveTo(0,210);
            Form1.Image1.Canvas.LineTo(511,210);
            Form1.Image1.Canvas.MoveTo(0,240);
            Form1.Image1.Canvas.LineTo(511,240);
            Form1.Image1.Canvas.MoveTo(0,270);
            Form1.Image1.Canvas.LineTo(511,270);
            Form1.Image1.Canvas.MoveTo(51,0);
            Form1.Image1.Canvas.LineTo(51,300);
            Form1.Image1.Canvas.MoveTo(102,0);
            Form1.Image1.Canvas.LineTo(102,300);
            Form1.Image1.Canvas.MoveTo(153,0);
            Form1.Image1.Canvas.LineTo(153,300);
            Form1.Image1.Canvas.MoveTo(204,0);
            Form1.Image1.Canvas.LineTo(204,300);
            Form1.Image1.Canvas.MoveTo(255,0);
            Form1.Image1.Canvas.LineTo(255,300);
            Form1.Image1.Canvas.MoveTo(306,0);
            Form1.Image1.Canvas.LineTo(306,300);
            Form1.Image1.Canvas.MoveTo(357,0);
            Form1.Image1.Canvas.LineTo(357,300);
            Form1.Image1.Canvas.MoveTo(408,0);
            Form1.Image1.Canvas.LineTo(408,300);
            Form1.Image1.Canvas.MoveTo(459,0);
            Form1.Image1.Canvas.LineTo(459,300);
            Form1.Image1.Canvas.MoveTo(510,0);
            Form1.Image1.Canvas.LineTo(510,300);
            //画边框
            Form1.Image1.Canvas.Pen.Style:=psSolid;
            Form1.Image1.Canvas.MoveTo(0,0);
            Form1.Image1.Canvas.LineTo(511,0);
            Form1.Image1.Canvas.MoveTo(0,299);
            Form1.Image1.Canvas.LineTo(511,299);
            Form1.Image1.Canvas.MoveTo(0,0);
            Form1.Image1.Canvas.LineTo(0,300);
            Form1.Image1.Canvas.MoveTo(511,0);
            Form1.Image1.Canvas.LineTo(511,300);
            bitblt(Form1.Canvas.Handle,Form1.Image1.Left,Form1.Image1.Top,512,300,Form1.Image1.canvas.handle,0,0,srccopy);end;
    在公司我用的机器上运行是8000多毫秒,在同事的机器上是1000多...另外发现一个问题,同样的这个程序,我在家里用delphi7编译的时候,不用用到btiblt,image1直接画直接显示画面不会闪烁,拿到公司这部机器编译后运行就很闪,得加上btiblt才不会闪,公司的环境是delphi6.....不知是不是跟delphi的版本有关~~~~~现在试不了~回家再重新试试~!
      

  14.   

    感觉用btiblt的速度比在Form里面开双缓冲速度快一半.
      

  15.   

    开心~~~~~知道是电脑的问题....不是我能力问题......一开始还很郁闷和我一起新进公司的那个同事很轻松就能达到500FPS....早上才发觉是因为没显卡驱动的原因~~~松了口气~!