Hy tommy2train,
i have checked your code setting 100000 points, the refreshing speed seems to be the same.
If i have well understood, at every tick all points are drawn; notwistanding this, it seems to be indipendent from their number.
Best regards, Enzo
Enzo,
The example that draws on a bitmap only draws the new point each clock tick, not all points. This what you did it in vb6.
That is the key to understand. See the bitmap? See there is only one point (line) drawn and in the timer event on the bitmap. Then the bitmap is shown.
The second example (above) is drawing in the paint event and draws all points each tick. See the for loop in the paint event that draws all the points (lines) each tick?
So the bitmap example draws one point each tick. The Paint event draws all the points (up to 30000 max at the end) each tick.
Comprende?
As Enzo has correctly infered eventually there will be enough points that the paint event draw all points method will be slower. Even if it takes 1,000,000 points the one drawing all points each tick will be slower. That is Enzo's question and logic. Not which faster but which is more efficient.
The two different examples prove the difference in the two different methods. That is all.
Yes Les you are correct one does not need to draw 30000 points the curve can be drawn with 1000. If all 30000 pts were drawn in an empty pixel the image would fill the picturebox. That is not the point.
Yes Castor your are correcct DirectX is faster. That is not the question.
Here is the draw only new points on bitmap example. This has just a couple additions from the version above.
The example makes the controls just copy and paste the code into an empty form. Change the form name as required.
'draw one point each tick on bitmap v2 Public Class Form7 Private WithEvents Timer1 As New Timer With {.Interval = 10} Private WithEvents Button1 As New Button With {.Parent = Me, .Text = "Start", .Location = New Point(20, 20), .ForeColor = Color.AntiqueWhite, .BackColor = Color.ForestGreen} Private WithEvents PictureBox1 As New PictureBox With {.Parent = Me, .BackColor = Color.Black, .BorderStyle = BorderStyle.FixedSingle} Private deltax, deltay As Single Private offset As Single Private count As Integer Private points(30000) As Single Private Sw As New Stopwatch Private Frames As Integer Private PicBmp As Bitmap Private PicG As Graphics Private x1 As Single = 0 Private Sub Form6_Load(sender As Object, e As EventArgs) Handles Me.Load Text = "Draw on Bitmap" ClientSize = New Size(500, 300) Form6_Resize(0, Nothing) End Sub Private Sub Form6_Resize(sender As Object, e As EventArgs) Handles Me.Resize Dim border As Integer = 20 PictureBox1.Top = Button1.Bottom + border PictureBox1.Left = border PictureBox1.Width = ClientSize.Width - (2 * border) PictureBox1.Height = ClientSize.Height - (PictureBox1.Top + border) PicBmp = New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height) PicG = Graphics.FromImage(PicBmp) deltay = PicBmp.Height deltax = CSng(PicBmp.Width / points.Length) offset = CSng(PicBmp.Height / 2) If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose() PictureBox1.Image = PicBmp End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click x1 = 0 count = 0 Frames = 0 Sw.Reset() Sw.Start() Timer1.Interval = 10 Timer1.Enabled = True End Sub Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick Dim fps As String = "0.0" Static nexttime As Long count = count + 1 points(count) = CSng((deltay * 0.3 * Math.Sin((10 / points.Length) * count)) + offset) If count > points.Length - 2 Then Timer1.Stop() 'Using bmp As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height) ' PictureBox1.DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height)) ' bmp.Save("c:\test\bitmap1.png") 'End Using End If With PicG 'show time every 500 ms Frames += 1 fps = (Frames / (nexttime / 1000)).ToString("f1") If Sw.ElapsedMilliseconds > nexttime Then nexttime = Sw.ElapsedMilliseconds + 500 End If .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias .FillRectangle(Brushes.Black, 0, 0, PictureBox1.ClientSize.Width, 30) .DrawString(count.ToString & " - " & fps & " fps " & (nexttime / 100).ToString("f0") & " secs", Me.Font, Brushes.White, 10, 10) If count > 1 Then .DrawLine(Pens.Red, x1, points(count - 1), x1 + deltax, points(count)) End If x1 += deltax End With PictureBox1.Invalidate() End Sub End Class
Enzo,
See how there is no paint event code in the above draw on bitmap v2 example?
See where the bitmap is declared at class level at the top?
Private PicBmp As Bitmap Private PicG As Graphics
Also see how the PicG is graphics surface is created from thePicBmp in the resize event (thus you can resize the form).
PicBmp = New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height) PicG = Graphics.FromImage(PicBmp)
With the draw on bitmap method, we draw on PicG the graphics surface for the bitmap in the timer tick event sub routine. Since we draw on a bitmap theimage is saved on the bitmap and we don't redraw it each tick. Instead we only draw the new points on the previously drawn bitmap and then .invalidate to copy the bitmap it to the screen.
In the draw in paint event sub routine we use e.graphics to drawon. The paint event is called each timer tick. The system clears the previous drawingand we redraw all the points again.
See the difference? One method we are saving the previously drawn image in the bitmap.The other method the system is clearing the image by giving us an empty bitmap e.graphics to draw on and we need to redraw the entire image all points each tick.
In most cases one only needs to draw in the paint event. If you filter your number of points (as Les showed) that is all you need.
Finally, I answered the question not you Enzo. The correct answer is my post showing the example code. You should mark my post as the answer not yours.
Adios