Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Go Back  Xtreme Visual Basic Talk > > > Invalidate, Timers, and loops and their pros /cons


Reply
 
Thread Tools Display Modes
  #1  
Old 02-04-2013, 10:07 PM
Under Study Under Study is offline
Regular
 
Join Date: Jul 2008
Posts: 83
Default Invalidate, Timers, and loops and their pros /cons


Im 99% positive there are several better ways to do what doing and after a few days of research im still not sure whats best.

Right now I have a timer that on each cycle moves an image( that is several times larger than the from) between 1-14 pixels (depending on user input) completely across the full screen from.

currently my timer looks like this
Code:
    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick

        Xpoint = Xpoint - dx 'slightly alters the  X & Y points on the image to make it move. 
        Ypoint = Ypoint - dy

        Invalidate() 'Redraws the form with undated image locations

    End Sub
The timer is set to run at 30 TPS, but the Invalidate line seems to be lagging the timer, and im only getting about 10 TPS. Ive read a few ways to get around this but im not sure which one would be the best. Some say adding more times running just Invalidate but that seems silly, some say to use a Do While Loop instead of a Timer, and some have said not skip Invalidate all together and use DirectX to display the image. The last one seems the smartest but ive heard the 2010 DirectX References around going to be phased out and might not work for much longer.

So whats the best way to go about this?

Thanks


------------------------------
Edit*
I also read about being about to draw the image once and "scroll" though what part is visible. It didn't explain how he did it, but I assume doing it like that, you wouldn't be able to draw it to the form itself. Right?

Thanks again

Last edited by Under Study; 02-04-2013 at 10:23 PM.
Reply With Quote
  #2  
Old 02-05-2013, 05:13 AM
DrPunk's Avatar
DrPunkInvalidate, Timers, and loops and their pros /cons DrPunk is offline
Senior Contributor

* Expert *
 
Join Date: Apr 2003
Location: Never where I want to be
Posts: 1,403
Default

The way you are doing your drawing/painting is far more important than any code you've pasted. That will be what is "lagging the Invalidate".

As far as I'm aware (which isn't maximum awareness) your method of refreshing with invalidate is OK. Someone more clued up might correct me on that though.

People here will only be able to help speed up the refresh if you can show how you're currently doing the drawing/painting to the form.
__________________
There are no computers in heaven!
Reply With Quote
  #3  
Old 02-05-2013, 10:55 AM
Rockoon's Avatar
Rockoon Rockoon is offline
Joseph Koss

* Guru *
 
Join Date: Aug 2003
Location: Unfashionable End
Posts: 3,615
Default

My guess is also that the paint event is what is taking that much time.

However, that doesnt mean that driving your animation with the timer is still a good idea.

Even though this isn't C#, I consider Tom Millers C# MSDN blog post titled My last post on rendering loops (hopefully).. to be the most definitive authority on the subject of what you are trying to do.
Reply With Quote
  #4  
Old 02-05-2013, 05:39 PM
Under Study Under Study is offline
Regular
 
Join Date: Jul 2008
Posts: 83
Default

My paint event is really simple

Code:
   Private Sub PaintForm(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        e.Graphics.DrawImage(blue, (Xpoint), (Ypoint), 50000, 50000)

    End Sub
Reply With Quote
  #5  
Old 02-05-2013, 06:46 PM
passel's Avatar
passelInvalidate, Timers, and loops and their pros /cons passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,028
Default

Quote:
Originally Posted by Under Study View Post
My paint event is really simple

Code:
   Private Sub PaintForm(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        e.Graphics.DrawImage(blue, (Xpoint), (Ypoint), 50000, 50000)

    End Sub
Unless I'm mis-interpreting something, I guess I don't currently have a computer where I could even atempt that.
50,000 x 50,000 pixels would be 2.5 billion pixels, and since .Net would use 4-bytes per pixel normally, that would be 10 billion bytes just for the pixel data for the image.
None of the machines I normally use have more then 8GB of dynamic memory at the moment so I can't imagine how you're even able to do a 10hz update.
Now if it were 5000 x 5000, then that would seem reasonable.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #6  
Old 02-06-2013, 03:20 AM
Under Study Under Study is offline
Regular
 
Join Date: Jul 2008
Posts: 83
Default

the image im calling is only 2500 x 2500 but calling it at 50000 x 50000 blows it up to show the portion of the portion of the image im wanting. Is there an easier way to do this and only show one image?

Edit*
--------------------
I went ahead and scaled my image up to 10000 x 10000 pixels and didnt try to scale it up in the invalidate event, but that just made it slower. So im out of ideas. Not sure if I need to ditch that method or just find a better way to do it. I ask my friend for some advice, he is a flash programer. He said i need to call the image up once and "scroll" though it... idk if that would work in vb or not.

Last edited by Under Study; 02-06-2013 at 03:31 AM.
Reply With Quote
  #7  
Old 02-06-2013, 03:52 AM
DrPunk's Avatar
DrPunkInvalidate, Timers, and loops and their pros /cons DrPunk is offline
Senior Contributor

* Expert *
 
Join Date: Apr 2003
Location: Never where I want to be
Posts: 1,403
Default

I'm not too sure I understand, but wouldn't one of the other DrawImage calls help.

One like -> http://msdn.microsoft.com/en-gb/library/ms142045.aspx

Quote:
Draws the specified portion of the specified Image at the specified location and with the specified size.
In other words you have your one buffered image loaded and then you specify the portion of that Image you want to display and where to put it.

That would let you scroll the image as far as I can tell, changing the source X for a marquee effect.
__________________
There are no computers in heaven!
Reply With Quote
  #8  
Old 02-06-2013, 04:32 AM
Under Study Under Study is offline
Regular
 
Join Date: Jul 2008
Posts: 83
Default

Im not sure how that differs from what im using, seems to be basically the same...no? Tried to give it a shot and its not letting me call the new event. Said the argument was not specified for the parameter of 'e'

Edit*
-------------------
Im dumb, figured what i did wrong but it still is giving me the same issue.

Last edited by Under Study; 02-06-2013 at 04:37 AM.
Reply With Quote
  #9  
Old 02-06-2013, 04:37 AM
DrPunk's Avatar
DrPunkInvalidate, Timers, and loops and their pros /cons DrPunk is offline
Senior Contributor

* Expert *
 
Join Date: Apr 2003
Location: Never where I want to be
Posts: 1,403
Default

I just get the idea that you're blowing up the WHOLE image so that only the portion that you want is visible.

This other way says, take this small bit of the image and blow THAT up to fill the area I have to display it in.

I think, anyway. I'm as confused as you.
__________________
There are no computers in heaven!
Reply With Quote
  #10  
Old 02-06-2013, 09:09 PM
Under Study Under Study is offline
Regular
 
Join Date: Jul 2008
Posts: 83
Default

Yeah, I get whats wrong, just not sure how to fix it. No matter what size the image is that im painting to the form, i need it to be at least 5x bigger than the form. So when im in full screen, the painting the full form slows down the timer im using. Idk what to do. Guess im going to pick up a vb directx book tomorrow and see what i can learn there.
Reply With Quote
  #11  
Old 02-06-2013, 10:36 PM
passel's Avatar
passelInvalidate, Timers, and loops and their pros /cons passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,028
Default

Probably the simplest way to improve the speed without a lot of effort would be to create a texture brush from the image and use it to fill the client area of the form.

Rather than include a large bitmap, I'll just code up a quick example that will copy the upper left 500 x 500 pixels of the screen and create a brush from that.
It will then use that brush to fill a 2500 x 2500 bitmap, representing your original 2500 x 2500 bitmap.
It will then create a texture brush from that bitmap to serve as the example you would create from your original image.
I now interpret your 50000 x 50000 draw image statement to meaning that you are blowing up the image 20x its original size.
So the code will use the TranslateTransform method to offset the brush (analogous to your offseting the drawimage destination X,Y), and use the ScaleTransform to make the brush 20x larger.

I didn't add a timer to measure the update rate, I'll leave that to you.
This example will just allow you to drag with the left mouse button on the form to "move" the image around.
Code:
Public Class Form1
  Dim srcBrush As TextureBrush
  Dim xoff, yoff As Integer

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.DoubleBuffered = True
    Dim tmpimg As New Bitmap(500, 500)
    Dim g As Graphics = Graphics.FromImage(tmpimg)
    g.CopyFromScreen(0, 0, 0, 0, New Size(500, 500))
    Dim tmpbrush As New TextureBrush(tmpimg)
    Dim srcBmp = New Bitmap(2500, 2500)
    g.Dispose()
    g = Graphics.FromImage(srcBmp)
    g.FillRectangle(tmpbrush, 0, 0, 2500, 2500)
    srcBrush = New TextureBrush(srcBmp)        '<---The statement to add to your code to convert your image to a texturebrush
    g.Dispose()
    tmpimg.Dispose()
    tmpbrush.Dispose()
    srcBmp.Dispose()
  End Sub

  Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    Static lastPnt As Point
    If e.Button = Windows.Forms.MouseButtons.Left Then
      xoff += e.X - lastPnt.X
      yoff += e.Y - lastPnt.Y
      Me.Refresh()
    End If
    lastPnt = e.Location
  End Sub

  Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    srcBrush.TranslateTransform(xoff, yoff)
    srcBrush.ScaleTransform(20, 20)
    e.Graphics.FillRectangle(srcBrush, Me.ClientRectangle)
    srcBrush.ResetTransform()
  End Sub
End Class
Be aware that at the time of this writing (and probably for the previous year or so), the later versions of Intenet Explorer might not allow you to scroll the code window far enough to see the all of the code.
If that is the case for you, you can drag the mouse on the web page just above the code window to a little beyond the code window and copy.
Paste that into an editor, eg. notepad, and you should see all of the code (with other "garbage" before and possibly after.)
You can then copy the code portion from the editor to paste in a new project.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 02-07-2013 at 08:46 AM.
Reply With Quote
  #12  
Old 02-07-2013, 10:44 AM
Under Study Under Study is offline
Regular
 
Join Date: Jul 2008
Posts: 83
Default

Passel, you have once again solved my problem! Thank you! This works so much better and solves several other problems I was having!

Really, thanks you! You always respond to my posts and you have taught me so much sense I started posting here.


*Edit
------------------
Do you know if it is possible to use the brush method to draw single images at a coordinate location and not the full form? I tried every option that made sense and could only get it a titled image on top of the base image from the code you gave. If i have to use a standard drawimage method, is there a way to differentiate what image im clicking on to run a different code? If so would that work for the brush method too?

Thanks

Last edited by Under Study; 02-07-2013 at 12:26 PM.
Reply With Quote
  #13  
Old 02-07-2013, 07:49 PM
passel's Avatar
passelInvalidate, Timers, and loops and their pros /cons passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,028
Default

Yes, I've posted a few examples that use a texture brush to draw single images at different locations.
I guess the easiest to find (the last one posted, I believe) is this thread (Graphics example based on Space Invaders).
That one might be of particular interest since you can look at the code attached to the first post, which is not using a texture brush to draw the aliens, and then look at the code attached to the third post, which is using texture brushes to draw the background and the aliens, to see how they compare.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #14  
Old 02-10-2013, 09:27 AM
Under Study Under Study is offline
Regular
 
Join Date: Jul 2008
Posts: 83
Default

Passel, thank you once again! I have learned much from your coding. I think the only question I have left is only I already know the answer to, but im hoping im wrong. In your Space Invaders game, unless im mistaken, you essentially viewed the aliens as rectangles when determining if the location was clicked or not. Currently im using the brush method from above to paint several different and sort of complex images of different types of tress (5 total), and when the user clicks on each tree, some text is shown. Nice and simple till this part. The pictures of the tress are image files with transparent backgrounds and so far ive defined them by their rectangular location on the form but this also means that if i click on the transparent part of the image, the click is still registering and displaying the text. So far Ive only found ways to define a location / coordinates on the form like this with the use of shapes in visual basic. Is there a way to do it when the area cant really be defined by a normal shape? I guess if I took the time to find the exact coordinates of each point on the tree image, it would work... but that seems like it would take a while and could be inaccurate. Just wanted to ask before I start doing it that way by hand.

Thanks!

Edit*
______________________

Ok, I think if figured it out, this maybe the long way, but it seems to be working.


Code:

        Dim colorxy As Color = My.Resources.treesX.GetPixel(ColorX, ColorY) 'This finds the color of the cell im clicking on
        If colorxy.A <> 0 Then   ' And if it is not transparent then i can show my text.  
            
           'Show Text
        End If

Thats been the simplest way ive been able to figure it out so far.

Last edited by Under Study; 02-10-2013 at 07:41 PM.
Reply With Quote
  #15  
Old 02-10-2013, 08:13 PM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default Point over transparent pixels test

Quote:
Originally Posted by Under Study
..so far I’ve defined them by their rectangular location on the form but this also means
that if I click on the transparent part of the image, the click is still registering..
I'm glad you found your own workaround code for this, but
you should also take a look at the attachment for post#36 (a working demo of this) in my Viewer thread.

Here's the code from inside that attachment:
Code:
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
  Dim pt As New Point(e.Location.X, e.Location.Y)
  'set offset from upper left corner of sprite to mousedown point
  mouse_offset = New Point((spriteLocation.Left - e.X), (spriteLocation.Top - e.Y))
  'Test if mousedown point is inside picture rectangle and over visible pixel
  If (PointIsOverPicture(e.X, e.Y)) Then
    bnlDragging = True
    lblDebug1.Text = "blnDragging = True"
  Else
    lblDebug1.Text = "blnDragging = False"
  End If
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
  If (e.Button = MouseButtons.Left) And (bnlDragging = True) Then
        spriteLocation.X = mouse_offset.X + e.X
        spriteLocation.Y = mouse_offset.Y + e.Y
        Me.Invalidate()
  Else
    ' We're not dragging the image. See if we're over it.
    Dim new_cursor As Cursor = Cursors.Default
    If (PointIsOverPicture(e.X, e.Y)) Then
        new_cursor = Cursors.Hand
    End If
    If (Me.Cursor <> new_cursor) Then Me.Cursor = new_cursor
  End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
  bnlDragging = False
End Sub
' Return true if the point is over the picture's current location
'Using pixel alpha component test for transparent pixels 
Private Function PointIsOverPicture(ByVal x As Integer, ByVal y As Integer) As Boolean
  'See if it's over the picture's bounding rectangle.
  If ((x < spriteLocation.Left) OrElse (y < spriteLocation.Top) OrElse _
      (x >= spriteLocation.Right) OrElse (y >= spriteLocation.Bottom)) _
          Then Return False
  ' See if the point is above a non-transparent pixel.
  Dim i As Integer = x - spriteLocation.X
  Dim j As Integer = y - spriteLocation.Y
  Return (bm1.GetPixel(i, j).A > 0) '<--- Alpha component of pixel test
End Function


If you look at some of the Vierwer thread posts past post #36 passel and I explore variable alpha thresholds for dragging.

You might also want to check out the "Public Shared Sub MouseDown" in the Render.Vb file of the "!_a_rpg2panel_dragging_v5q.zip" attachment
to this post which contains similar code that first does a rectangle.contains test then (nested) an alpha (transparent) pixel test.

Of course that attachment is a wee bit advanced,
(but if you understood passel's QuickSpaceInvaders example
that code shouldn't be too hard to figure out).

The original (much simpler) code for alpha pixel test when dragging is from:
vbHelper: Let the user drag an image with transparent pixels over a background image in Visual Basic .NET

Last edited by surfR2911; 02-10-2013 at 08:27 PM.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
 
Invalidate, Timers, and loops and their pros /cons
Invalidate, Timers, and loops and their pros /cons
 
-->