Experts ~ Drawing Efficiency (500fps) Delphi/Windows SDK/API
Http://www.delphi2007.net/DelphiMultimedia/html/delphi_20061018141036227.html
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 ));
-------------------------------------------------------------------------
Dual buffering is used. Code The execution result is 1100 milliseconds.
If I add Pb. Canvas. Draw (0, 0, _ drawmap); the execution result will be 9900 milliseconds, which is 10 times less efficient.
Is there any way to add this sentence without changing the efficiency ~?
Give me some ideas ~~
Drawing operations that take up a large amount of computing time cannot use the method of drawing directly on picturebox. This method is very inefficient and will not be used for a long time.ProgramNow, I cannot explain the specific method clearly. You can check it and give you a thought.
Step 1: Calculate the required drawing data
Step 2: Draw a graph on the Memory Page (generally a bitmap object) (the two steps take a long time)
Step 3: directly use the display component (for example, picturebox) to directly call the painted Memory Page and display it.
Use the number of memory pages as needed.
If it takes a lot of time to compute and draw a graph, this drawing program cannot reduce the drawing time, but the above method is used, the painting process can be eliminated (at least invisible to users) without flashing. In addition, the drawing time of the Memory Page is faster than that of the direct drawing and display.
It seems that bitblt functions are required. If components do not provide similar methods, Windows APIs are required.
I just used tbitmap in the memory ~~ Then I found out that when I posted it,
PB. Canvas. Draw (0, 0, _ drawmap );
Special time consumption ~~~
If Pb. Canvas. Draw (, _ drawmap) is not executed, the execution speed is much faster ~
_ Drawmap is a tbitmap.
The display is time-consuming. You need to copy data from memory to memory, that is, using bitblt directly is not much faster.
If you do not need the animation effect, you can update the display after the animation is complete. Otherwise, you can use a single thread (timer can also be used) to update the display. It is enough to update the display every 15-30 times, there is no need for 50 frames per second as you do now.
The problem is that the company needs .....
Because the sampling frequency from waveforms is very high... if the number of frames is low, some important information collected may be missed .....
Didn't you save them all? If it is not displayed, it will not be lost.
Not afraid of loss, but must be displayed in real time ....
30 FPS is displayed in real time.
It doesn't make sense if you have to pay more than 50 FPS.
For I: = 0 to 500 do
Begin
Getdata ();
Drawdata ();
// Pb. Canvas. Draw (0, 0, _ drawmap );
End;
The requirement is too high. What software is required? If efficient plotting is required, use DirectX instead of the original method.
DirectX ~~~ What development tools do not need to be installed ~~~
Never used ~~~~
Can you give me a small example ~~?
To install the DirectX Development Kit, I cannot get the example now, and it is certainly not easy to get started. This is generally only required for 3D games. First, you need to understand your needs.
I don't know your specific needs. I just want to discuss it:
1) if the data you sample is historical incremental data, you only need to update the data on it, instead of redrawing the entire image. That is to say, your drawdata should be directly painted on the Pb canvas. I think it will not be very large if the new data volume is large.
2) if the new data is really large, you can only use DirectX.
3) If your program gives you the idea, you can combine them into one frame during display.
OpenGL can be used to see the nehe getting started example.
In addition, the teechart control package contains the encapsulated OpenGL chart.
Netfly (pivot) is right. You can consider only repainting the changed part, not all of which.
It's just a simple 2D graph, and the speed is almost the same. It is not how fast you can use DirectX (or DirectDraw in DirectX) or OpenGL.
If you are displaying a continuously changing waveform (because you have the name timer_getwave), you can use scrolldc to scroll the previous image (left to right or right to left ), then, draw the updated part.
Thank you!
Now the problem is solved! I laughed and got depressed for many days.
......
I wrote about waveform display for industrial ultrasonic flaw detection.
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 ('actual elapsed time' + floattostr (T3) + 'millisecond ');
Self. button1.enabled: = true;
End;
// Obtain simulation data
Procedure getpoints;
VaR
X: integer;
Begin
// Obtain data
For X: = 0 to 511 do
Begin
Drawpoints [X]. X: = X;
Drawpoints [X]. Y: = random (300 );
End;
End;
// Draw
Procedure draw;
Begin
// Draw the background into the cache
Form1.image1. Canvas. Brush. Color: = clblack;
Form1.image1. Canvas. fillrect (rect (0, 0, 512,300 ));
// Draw the waveform into the cache
Form1.image1. Canvas. Pen. Style: = pssolid;
Form1.image1. Canvas. Pen. Color: = clgreen;
Form1.image1. Canvas. polyline (drawpoints );
// Draw a grid into the cache
Form1.image1. Canvas. Pen. Style: = psdot;
Form1.image1. Canvas. Pen. Color: = clred;
Form1.image1. Canvas. moveTo (0, 30 );
Form1.image1. Canvas. lineto (random, 30 );
Form1.image1. Canvas. moveTo (0, 60 );
Form1.image1. Canvas. lineto (values, 60 );
Form1.image1. Canvas. moveTo (0, 90 );
Form1.image1. Canvas. lineto (numbers, 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 );
// Draw a border
Form1.image1. Canvas. Pen. Style: = pssolid;
Form1.image1. Canvas. moveTo (0, 0 );
Form1.image1. Canvas. lineto (values, 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 (values, 0 );
Form1.image1. Canvas. lineto (511,300 );
Bitblt (form1.canvas. Handle, form1.image1. Left, form1.image1. Top, 512,300, form1.image1. Canvas. Handle, srccopy );
End;
It takes more than 8000 milliseconds to run on the machine I used in the company, and more than 1000 on my colleague's machine...
In addition, I found a problem. In this program, I didn't need to use btiblt when compiling with Delphi7 at home. image1 directly showed that the screen would not flash, after obtaining the compilation of the company's machine, the Operation will flash, and the btiblt will not flash. The company's environment is delphi6 .....
I wonder if it is related to the Delphi version ~~~~~
I cannot try it now ~ Go home and try again ~!
Btiblt is faster than double buffering in form.
Happy ~~~~~ I know it's a computer problem... it's not a problem with my abilities ......
At the beginning, I was very depressed. The new employee with me was able to easily reach FPS... I found out in the morning that it was caused by no video card driver ~~~ Relieved ~!