none
Drawing on desktop faster

    Question

  • I'm writting a simple art application shows falling ~50% transparent circles.

    Here is how it works: 

    1.

    • Fill in the collection of Ci (Ci is the circle-define class). It's natural randomly. 
    • Maximize the form, and set it's borderstyle to None.

    2. Draw the circles by each different circle definition to a bitmap (consider the form10.vb in the package below).

    3. Use AlphaFormTransformer (on this site) to remove the form background, and it seems it draws on desktop.

    I have uploaded the project here

    You can see, it runs slowly. I can understand that draw on a very large bitmap and update it by a timer is a hard job for processors.

    And I need it runs faster, or any code optimizations. 

    Thanks in advance.


    Call me Zenocoding

    Tuesday, May 28, 2013 9:49 AM

Answers

  • I changed up your code with help from this thread. http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/de00072e-8b97-4095-95f8-6fc2849e9faa

    May work better for you with backcolor and transparencykey set to white though.

    Imports System.Collections.ObjectModel Public Class Form1 Const MaxCircles = 200 Const MaxRadius = 50 Class Ci Friend X As Integer Friend Y As Integer Friend Radius As Byte Friend delt As Integer Friend Color As Color Friend Brush As SolidBrush Public Sub Increase() Y += delt End Sub Sub Reset() Y = -Radius End Sub End Class Dim circles As New Collection(Of Ci) Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Me.TopMost = True

    Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None Me.BackColor = Color.Red Me.TransparencyKey = Color.Red Timer1.Interval = 100 Me.DoubleBuffered = True Me.Width = Screen.PrimaryScreen.WorkingArea.Width Me.Height = Screen.PrimaryScreen.WorkingArea.Height For i As Integer = 1 To MaxCircles Dim c As Ci = GenerateCircle() circles.Add(c) Next Timer1.Enabled = True Me.Location = Point.Empty End Sub Private Function GenerateCircle() As Ci Dim c As New Ci c.Radius = CInt(Math.Ceiling(Rnd() * MaxRadius)) c.X = CInt(Math.Ceiling(Rnd() * Me.Width)) c.Y = CInt(Math.Ceiling(Rnd() * Me.Height)) c.delt = CInt(Math.Ceiling(Rnd() * 3)) Dim r As Byte = 127 + CInt(Math.Ceiling(Rnd() * 127)) Dim b As Byte = CInt(Math.Ceiling(Rnd() * 248)) Dim g As Byte = CInt(Math.Ceiling(Rnd() * 127)) c.Color = Color.FromArgb(78, r, g, b) c.Brush = New SolidBrush(c.Color) Return c End Function Private Sub IncreaseY() For Each c As Ci In circles c.Increase() If c.Y > Me.Height Then c.Reset() Next End Sub Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias For Each c As Ci In circles e.Graphics.FillEllipse(c.Brush, c.X, c.Y, c.Radius, c.Radius) Next End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick IncreaseY() Me.Invalidate() End Sub End Class



    This is what it looks like set to white.

    You've taught me everything I know but not everything you know.




    • Edited by Mr. Monkeyboy Tuesday, May 28, 2013 8:18 PM
    • Marked as answer by Zenocoding Thursday, May 30, 2013 12:47 AM
    Tuesday, May 28, 2013 7:56 PM

All replies

  • Zenocoding,

    Your problem is very depending from your video adapter, OS and processor and memory installed. Therefore tell that at least.


    Success
    Cor

    Tuesday, May 28, 2013 10:13 AM
  • My computer profile: Windows XP SP3, Pentium G850, 1gb DDR3 1333 and no external graphics card.

    Or should it be better if it is a screen-saver instead of drawing to desktop? - It's a pitty if everyone run it as a screen saver.


    Call me Zenocoding


    • Edited by Zenocoding Tuesday, May 28, 2013 11:47 AM
    Tuesday, May 28, 2013 11:40 AM
  • I changed up your code with help from this thread. http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/de00072e-8b97-4095-95f8-6fc2849e9faa

    May work better for you with backcolor and transparencykey set to white though.

    Imports System.Collections.ObjectModel Public Class Form1 Const MaxCircles = 200 Const MaxRadius = 50 Class Ci Friend X As Integer Friend Y As Integer Friend Radius As Byte Friend delt As Integer Friend Color As Color Friend Brush As SolidBrush Public Sub Increase() Y += delt End Sub Sub Reset() Y = -Radius End Sub End Class Dim circles As New Collection(Of Ci) Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Me.TopMost = True

    Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None Me.BackColor = Color.Red Me.TransparencyKey = Color.Red Timer1.Interval = 100 Me.DoubleBuffered = True Me.Width = Screen.PrimaryScreen.WorkingArea.Width Me.Height = Screen.PrimaryScreen.WorkingArea.Height For i As Integer = 1 To MaxCircles Dim c As Ci = GenerateCircle() circles.Add(c) Next Timer1.Enabled = True Me.Location = Point.Empty End Sub Private Function GenerateCircle() As Ci Dim c As New Ci c.Radius = CInt(Math.Ceiling(Rnd() * MaxRadius)) c.X = CInt(Math.Ceiling(Rnd() * Me.Width)) c.Y = CInt(Math.Ceiling(Rnd() * Me.Height)) c.delt = CInt(Math.Ceiling(Rnd() * 3)) Dim r As Byte = 127 + CInt(Math.Ceiling(Rnd() * 127)) Dim b As Byte = CInt(Math.Ceiling(Rnd() * 248)) Dim g As Byte = CInt(Math.Ceiling(Rnd() * 127)) c.Color = Color.FromArgb(78, r, g, b) c.Brush = New SolidBrush(c.Color) Return c End Function Private Sub IncreaseY() For Each c As Ci In circles c.Increase() If c.Y > Me.Height Then c.Reset() Next End Sub Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias For Each c As Ci In circles e.Graphics.FillEllipse(c.Brush, c.X, c.Y, c.Radius, c.Radius) Next End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick IncreaseY() Me.Invalidate() End Sub End Class



    This is what it looks like set to white.

    You've taught me everything I know but not everything you know.




    • Edited by Mr. Monkeyboy Tuesday, May 28, 2013 8:18 PM
    • Marked as answer by Zenocoding Thursday, May 30, 2013 12:47 AM
    Tuesday, May 28, 2013 7:56 PM
  • Oh thank you guys!

    So, ignore the drawing quality, the transparent of circles and get the speed is the choice for this problem, just cause AlphaFormTransformer code causes the app runs so slowly.

    But wait! I've another thing to ask:

    Don't believe it just cost around 5% of my cpu!

    But how? Developer overview of Wmplayer says "You can draw on the device context with standard Microsoft Windows Graphics Device Interface (GDI) functions, using pens and brushes to create designs that are modified by the audio data supplied to you by Windows Media Player. GDI provides a rich set of drawing tools that can create many kinds of visual effects."

    It's something different in speed when i uses gdi+ (system.drawing) to render something like this (I've been building a simple audio player, which returns an audio data (I get 16 frequencies band): Draw 16 bars (16 rectangles) every 100 miliseconds. The drawing cost all my cpu, when you can see that in wmplayer's visualization window draws, (blend and fade out) many lines at same time, and without cost much cpu. I did change the drawing code to a background worker, lower it's cpu priority, or even processor affinity but no helps.

    So how can wmplayer draws it too fast?


    Call me Zenocoding

    Wednesday, May 29, 2013 1:11 PM
  • Did anybody answer your original question? And why don't you start a new thread for your new question.

    You've taught me everything I know but not everything you know.

    Wednesday, May 29, 2013 3:04 PM
  • Zenocoding:

    You can try to use Profiling tool to find the bottleneck, then try to improve the performance for that part:

    http://msdn.microsoft.com/en-us/library/z9z62c29.aspx


    Best regards,
    Riquel

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, May 29, 2013 8:13 PM
  • Oh yeah i'll start a new discuss.

    Call me Zenocoding

    Thursday, May 30, 2013 12:34 AM