For Programmers: Free Programming Magazines  


Home > Archive > Visual Basic > April 2006 > 2D graphics & speed quest









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author 2D graphics & speed quest
Jacquelin Hardy

2006-04-21, 6:56 pm

Hello group,

I wrote a marine software with vector charts. The charts are made of
polygons, lines and points. Polygons and lines each have a bounding box to
determine if they are in the viewing screen or not.

My question is: would I gain in speed display by using DirectX or OpenGL
rather than VB6 alone and some APIs like Polypolygon ?

Thank you

Jacquelin Hardy


Mike D Sutton

2006-04-21, 6:56 pm

> I wrote a marine software with vector charts. The charts are made of
> polygons, lines and points. Polygons and lines each have a bounding box to
> determine if they are in the viewing screen or not.
>
> My question is: would I gain in speed display by using DirectX or OpenGL
> rather than VB6 alone and some APIs like Polypolygon ?


In most cases, yes, these APIs use dedicated graphics hardware rather than
consuming CPU time that could be better spent elsewhere in your application.
The amount of acceleration is based on how complex the datasets are and how
often they change, and it also opens up more graphical possibilities such as
transparency and texture mapping.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Mike Williams

2006-04-21, 6:56 pm

"Jacquelin Hardy" <jachardy@videotron.ca> wrote in message
news:Fr72g.30120$5l2.299724@wagner.videotron.net...

> I wrote a marine software with vector charts. The charts are
> made of polygons, lines and points. Polygons and lines each
> have a bounding box to determine if they are in the viewing
> screen or not. My question is: would I gain in speed display
> by using DirectX or OpenGL rather than VB6 alone and
> some APIs like Polypolygon ?


No idea about DirectX. Never used it. But PolyLine and PolyPolyLine are
quite fast. Are you saying that you are currently using mostly the various
"poly" API functions and that they are too slow for your purposes? Have you
tried creating a metafile that includes your entire drawing and then just
"playing" the metafile? To be perfectly honest I've never done that myself
either, so I don't know how the speed would compare, but it might be worth
looking into.

Mike


Ralph

2006-04-21, 6:56 pm


"Jacquelin Hardy" <jachardy@videotron.ca> wrote in message
news:Fr72g.30120$5l2.299724@wagner.videotron.net...
> Hello group,
>
> I wrote a marine software with vector charts. The charts are made of
> polygons, lines and points. Polygons and lines each have a bounding box to
> determine if they are in the viewing screen or not.
>
> My question is: would I gain in speed display by using DirectX or OpenGL
> rather than VB6 alone and some APIs like Polypolygon ?
>
> Thank you
>
> Jacquelin Hardy
>


It really depends on what you are doing and your particular problem domain.

While not an expert in drawing, I have been in on projects where this
subject often comes up and it inevitably turns into a "Name that Tune"
contest among the experts, with DirectX usually getting the performance nod
in the end. However, that is between the experts and someone that knows what
they are doing can tweak their toy of choice to do some remarkable things,
and do it rather quickly. The real key is to select one and abuse the h*ll
out of it.

Also I have been amazed to discover that various 'drawing libraries' are not
as interchangeable as one might expect. Choosing one or the other often
requires subtle but far-reaching adjustments to the architecture of your
application. So again, best to pick one and lean it.

If future upgrades are of any concern then select either DirectX or OpenGL.
Currently MS seems to be favoring OpenGL.

hth
-ralph


Mike D Sutton

2006-04-21, 6:56 pm

> Have you tried creating a metafile that includes your entire drawing and
> then just "playing" the metafile? To be perfectly honest I've never done
> that myself either, so I don't know how the speed would compare, but it
> might be worth looking into.


A metafile is literally just a recording of GDI calls which are 'played
back' to re-render the picture, so performance will be exactly the same in
this regard.
One thing I forgot to mention in my prior post is that complex polygons will
require triangulation before they can be rendered by any 3D library (which
only essentially understands triangles.) If you're dealing with complex
polygons, especially those with self-intersections, then this may be a
sticking point since you'll need to find a good triangulation library to
take advantage of the libraries acceleration in this respect.
Scanline conversion, which is what GDI is doing which is renders a polygon,
takes care of this kind of thing for you when the polygon is rasterised so
you needn't worry about it there. As Ralph says, each library has their own
way of doing things which may affect your decision to use them and how you
architect your solution.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Mike Williams

2006-04-21, 6:56 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:uvZEt0WZGHA.508@TK2MSFTNGP02.phx.gbl...

> A metafile is literally just a recording of GDI calls which are
> 'played back' to re-render the picture, so performance will
> be exactly the same in this regard.


Yes it is. But, as you almost certainly already know, much of the time that
the API uses to process the various API drawing functions is spent analyzing
the device context before even a single pixel gets drawn. That is why
PolyLine is very much faster than using numerous seperate API calls to draw
each of the lines "one at a time". As I said in my earlier response, I don't
actually know whether playing a metafile will be any quicker than drawing
each of the components individually (because I've never tested it) but I
thought that it might be worth checking out, which is why I suggested it. If
the metafile structure simply calls a "fresh" API drawing routine for every
single element of a drawing then it will of course be no faster, and
possibly quite a bit slower, but if it instead does all of the "analyse the
device context" just once, and then draws the elements it might be faster.

Thinking some more about it, I'd probably tend to agree with you because I
really cannot see a mechanism whereby it can do the "annalyze the device
context" just once stuff, and in that case in it probably just draws each
element seperately, so that each of the individual API routines it calls
have to analyze the device context every time anyway. The simple fact is
that I did not actually know what it does (which is why I said, "it might be
worth looking into). However, if you already know for a fact that a metafile
is simply a recording of API calls (which it appears you do, and which is
something I wasn't quite sure of) then I bow to your superior knowledge ;-)

Mike



Mike D Sutton

2006-04-21, 6:56 pm

> Yes it is. But, as you almost certainly already know, much of the time
> that the API uses to process the various API drawing functions is spent
> analyzing the device context before even a single pixel gets drawn.


Hmm, I guess there may be some overhead there based on the graphics driver
but for the most part apart from pre-calculation of lookup tables and
allocation of buffers I don't see what analysis would bee to be made since,
assuming the destination is a DDB, the data is already in the most efficient
device dependant form and managed by the driver. There would of course be
some overhead to calling into a DLL each time though.
If you know of any literature on the subject to the contrary then I'd be
interested in finding out more though.

> That is why PolyLine is very much faster than using numerous seperate API
> calls to draw each of the lines "one at a time".


This is not necessarily correct.. I'm seeing LineTo() taking half the time
to draw the same shape as PolyLine() here.. To be honest these results were
a surprise to me too, I would have agreed with you that PolyLine() _should_
be faster especially since we've got the overhead of calling a DLL for each
line segment:

'*** Using: http://edais.mvps.org/Code/Librarie...lsStopWatch.cls
Private Declare Function MoveToEx Lib "GDI32.dll" (ByVal hDC As Long, _
ByVal X As Long, ByVal Y As Long, ByRef lpPoint As Any) As Long
Private Declare Function LineTo Lib "GDI32.dll" (ByVal hDC As Long, _
ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function Polyline Lib "GD32.dll" (ByVal hDC As Long, _
ByRef lpPoint As PointAPI, ByVal nCount As Long) As Long

Private Type PointAPI
X As Long
Y As Long
End Type

Private Sub Form_Click()
Dim MyPts() As PointAPI
Dim LoopPts As Long
Dim StopWatch As clsStopWatch
Dim LoopDraw As Long
Dim Times(0 To 1) As Double

Const NumPts As Long = 1000
Const NumDraw As Long = 100

' Generate a random polygon
ReDim MyPts(0 To NumPts - 1) As PointAPI
For LoopPts = 0 To NumPts - 1
MyPts(LoopPts).X = Rnd() * 1000
MyPts(LoopPts).Y = Rnd() * 1000
Next LoopPts

Set StopWatch = New clsStopWatch

Call StopWatch.StartTimer ' Profile PolyLine()
For LoopDraw = 0 To NumDraw - 1
Call Polyline(Me.hDC, MyPts(0), NumPts)
Next LoopDraw
Call StopWatch.StopTimer
Times(0) = StopWatch.Interval

Call StopWatch.StartTimer ' Profile MoveToEx()/LineTo()
For LoopDraw = 0 To NumDraw - 1
Call MoveToEx(Me.hDC, MyPts(0).X, MyPts(0).Y, ByVal 0&)

For LoopPts = 1 To NumPts - 1
Call LineTo(Me.hDC, MyPts(LoopPts).X, MyPts(LoopPts).Y)
Next LoopPts
Next LoopDraw
Call StopWatch.StopTimer
Times(1) = StopWatch.Interval

Set StopWatch = Nothing

' Display results
Call MsgBox( _
"PolyLine(): " & Format$(Times(0), "0.00") & vbCrLf & _
"LineTo(): " & Format$(Times(1), "0.00"))
End Sub
'***

When the form is fully displayed (i.e. no clipping) I'm getting for
following results:
PolyLine(): 3229.29
LineTo(): 1717.85

PolyLine() does however appear to be slightly more efficient at clipping
large areas of the dataset though which may have skewed your previous test
results? Wait, you did test before posting that previous statement,
right?..

> As I said in my earlier response, I don't actually know whether playing a
> metafile will be any quicker than drawing each of the components
> individually (because I've never tested it) but I thought that it might be
> worth checking out, which is why I suggested it. If the metafile structure
> simply calls a "fresh" API drawing routine for every single element of a
> drawing then it will of course be no faster, and possibly quite a bit
> slower, but if it instead does all of the "analyse the device context"
> just once, and then draws the elements it might be faster.


There's no short circuiting of GDI calls going on here, metafiles are really
pretty primitive beasts - What goes in one end comes out the other end. You
can quite easily write a PlayEnhMetaFile() method from scratch by simply
enumerating the records and calling the appropriate GDI calls. Indeed I've
written such a routine that takes the data and re-formats it on the fly to
draw wide cosmetic lines (for sub-sampling purposes) which actually
outperformed PlayEnhMetaFile() before the geometric pens were substituted.

> Thinking some more about it, I'd probably tend to agree with you because I
> really cannot see a mechanism whereby it can do the "annalyze the device
> context" just once stuff, and in that case in it probably just draws each
> element seperately, so that each of the individual API routines it calls
> have to analyze the device context every time anyway. The simple fact is
> that I did not actually know what it does (which is why I said, "it might
> be worth looking into). However, if you already know for a fact that a
> metafile is simply a recording of API calls (which it appears you do, and
> which is something I wasn't quite sure of) then I bow to your superior
> knowledge ;-)


Sure, but don't just take my word for it:

<quote src="http://msdn.microsoft.com/library/en-us/gdi/metafile_8tgz.asp">
The remaining records, which constitute the bulk of any metafile, correspond
to the graphics device interface (GDI) functions required to draw the
picture.
</quote>

Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Jacquelin Hardy

2006-04-21, 9:56 pm

Is DirectX or OpenGL of any use for speed purposes in a software like the
one you just wrote Mike ?
I am using polypolylgon to display about 100,000 points for a vector chart.


JH
"Mike D Sutton" <EDais@mvps.org> a écrit dans le message de news:
u1IADOZZGHA.3448@TK2MSFTNGP04.phx.gbl...
>
> Hmm, I guess there may be some overhead there based on the graphics driver
> but for the most part apart from pre-calculation of lookup tables and
> allocation of buffers I don't see what analysis would bee to be made
> since, assuming the destination is a DDB, the data is already in the most
> efficient device dependant form and managed by the driver. There would of
> course be some overhead to calling into a DLL each time though.
> If you know of any literature on the subject to the contrary then I'd be
> interested in finding out more though.
>
>
> This is not necessarily correct.. I'm seeing LineTo() taking half the time
> to draw the same shape as PolyLine() here.. To be honest these results
> were a surprise to me too, I would have agreed with you that PolyLine()
> _should_ be faster especially since we've got the overhead of calling a
> DLL for each line segment:
>
> '*** Using: http://edais.mvps.org/Code/Librarie...lsStopWatch.cls
> Private Declare Function MoveToEx Lib "GDI32.dll" (ByVal hDC As Long, _
> ByVal X As Long, ByVal Y As Long, ByRef lpPoint As Any) As Long
> Private Declare Function LineTo Lib "GDI32.dll" (ByVal hDC As Long, _
> ByVal X As Long, ByVal Y As Long) As Long
> Private Declare Function Polyline Lib "GD32.dll" (ByVal hDC As Long, _
> ByRef lpPoint As PointAPI, ByVal nCount As Long) As Long
>
> Private Type PointAPI
> X As Long
> Y As Long
> End Type
>
> Private Sub Form_Click()
> Dim MyPts() As PointAPI
> Dim LoopPts As Long
> Dim StopWatch As clsStopWatch
> Dim LoopDraw As Long
> Dim Times(0 To 1) As Double
>
> Const NumPts As Long = 1000
> Const NumDraw As Long = 100
>
> ' Generate a random polygon
> ReDim MyPts(0 To NumPts - 1) As PointAPI
> For LoopPts = 0 To NumPts - 1
> MyPts(LoopPts).X = Rnd() * 1000
> MyPts(LoopPts).Y = Rnd() * 1000
> Next LoopPts
>
> Set StopWatch = New clsStopWatch
>
> Call StopWatch.StartTimer ' Profile PolyLine()
> For LoopDraw = 0 To NumDraw - 1
> Call Polyline(Me.hDC, MyPts(0), NumPts)
> Next LoopDraw
> Call StopWatch.StopTimer
> Times(0) = StopWatch.Interval
>
> Call StopWatch.StartTimer ' Profile MoveToEx()/LineTo()
> For LoopDraw = 0 To NumDraw - 1
> Call MoveToEx(Me.hDC, MyPts(0).X, MyPts(0).Y, ByVal 0&)
>
> For LoopPts = 1 To NumPts - 1
> Call LineTo(Me.hDC, MyPts(LoopPts).X, MyPts(LoopPts).Y)
> Next LoopPts
> Next LoopDraw
> Call StopWatch.StopTimer
> Times(1) = StopWatch.Interval
>
> Set StopWatch = Nothing
>
> ' Display results
> Call MsgBox( _
> "PolyLine(): " & Format$(Times(0), "0.00") & vbCrLf & _
> "LineTo(): " & Format$(Times(1), "0.00"))
> End Sub
> '***
>
> When the form is fully displayed (i.e. no clipping) I'm getting for
> following results:
> PolyLine(): 3229.29
> LineTo(): 1717.85
>
> PolyLine() does however appear to be slightly more efficient at clipping
> large areas of the dataset though which may have skewed your previous test
> results? Wait, you did test before posting that previous statement,
> right?..
>
>
> There's no short circuiting of GDI calls going on here, metafiles are
> really pretty primitive beasts - What goes in one end comes out the other
> end. You can quite easily write a PlayEnhMetaFile() method from scratch
> by simply enumerating the records and calling the appropriate GDI calls.
> Indeed I've written such a routine that takes the data and re-formats it
> on the fly to draw wide cosmetic lines (for sub-sampling purposes) which
> actually outperformed PlayEnhMetaFile() before the geometric pens were
> substituted.
>
>
> Sure, but don't just take my word for it:
>
> <quote
> src="http://msdn.microsoft.com/library/en-us/gdi/metafile_8tgz.asp">
> The remaining records, which constitute the bulk of any metafile,
> correspond to the graphics device interface (GDI) functions required to
> draw the picture.
> </quote>
>
> Hope this helps,
>
> Mike
>
>
> - Microsoft Visual Basic MVP -
> E-Mail: EDais@mvps.org
> WWW: Http://EDais.mvps.org/
>



Mike Williams

2006-04-21, 9:56 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:u1IADOZZGHA.3448@TK2MSFTNGP04.phx.gbl...

> Hmm, I guess there may be some overhead there based on the graphics
> driver but for the most part apart from pre-calculation of lookup tables
> and allocation of buffers I don't see what analysis would bee to be made
> since, assuming the destination is a DDB, the data is already in the most
> efficient device dependant form and managed by the driver. There would
> of course be some overhead to calling into a DLL each time though.
> If you know of any literature on the subject to the contrary then I'd be
> interested in finding out more though.


Hmm, no literature I'm afraid. I usually give far more credence to empirical
evidence, which is usually the most reliable anyway and which tells me that
repeatedly calling an API routine to perform a certain task is almost always
very much slower than calling a similar API routine that gets the same job
"done in one go".

> PolyLine() does however appear to be slightly more efficient at
> clipping large areas of the dataset though which may have skewed
> your previous test results? Wait, you did test before posting that
> previous statement, right?..


My previous test results were not skewed by anything, although I think your
own might have been? And yes, I did test before posting, which incidentally
appears to be more than you did or you would almost certainly have noticed
the problem with the PolyLine declaration in the code you posted, right?..

> This is not necessarily correct.. I'm seeing LineTo() taking half the
> time to draw the same shape as PolyLine(). To be honest these results
> were a surprise to me too, I would have agreed with you that
> PolyLine() _should_ be faster especially since we've got the
> overhead of calling a DLL for each line segment:


Actually, PolyLine() _is_ faster. It's just that your test code causes other
things to happen that are not being taken into account. Remember, I'm
talking about the speed of PolyLine versus the equivalent bunch of LineTo
calls, and so I'm only interested in the time _those specific routines_ take
to draw their output, without anything else getting in the way of the
results. The problem with the code you posted is that a whole bunch of
display refreshes is going on at the same time, which tends to swamp things.
If you use your exact same code but set the Form's Autoredraw property to
True you will see an entirely different result. Both of them (PolyLine and
the bunch of LineTo stuff) will of course be very much faster than they were
before (because we've got the display refreshes out of the way) and in
addition you'll see that PolyLine is actually very much faster than the
bunch of LineTo calls. Most people do most of their drawing to offscreen
buffers anyway, and only dump the result to the screen when it is done, so
drawing to an offscreen buffer is a perfectly valid way of testing the speed
of these things. At this end I'm getting a massive speed increase all round
(as you would of course expect) and I'm seeing PolyLine about _a hundred
times faster_ than the equivalent bunch of LineTo statements. Here's your
own code but using Autoredraw = True. Let me know what you get at your end.

Hope this helps.

Mike

'*** Using: http://edais.mvps.org/Code/Librarie...lsStopWatch.cls
Private Declare Function MoveToEx Lib "GDI32.dll" (ByVal hDC As Long, _
ByVal X As Long, ByVal Y As Long, ByRef lpPoint As Any) As Long
Private Declare Function LineTo Lib "GDI32.dll" (ByVal hDC As Long, _
ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function Polyline Lib "GDI32.dll" (ByVal hDC As Long, _
ByRef lpPoint As PointAPI, ByVal nCount As Long) As Long

Private Type PointAPI
X As Long
Y As Long
End Type

Private Sub Form_Click()
Me.AutoRedraw = True
Dim MyPts() As PointAPI
Dim LoopPts As Long
Dim StopWatch As clsStopWatch
Dim LoopDraw As Long
Dim Times(0 To 1) As Double

Const NumPts As Long = 1000
Const NumDraw As Long = 100

' Generate a random polygon
ReDim MyPts(0 To NumPts - 1) As PointAPI
For LoopPts = 0 To NumPts - 1
MyPts(LoopPts).X = Rnd() * 1000
MyPts(LoopPts).Y = Rnd() * 1000
Next LoopPts

Set StopWatch = New clsStopWatch

Call StopWatch.StartTimer ' Profile PolyLine()
For LoopDraw = 0 To NumDraw - 1
Call Polyline(Me.hDC, MyPts(0), NumPts)
Next LoopDraw
Call StopWatch.StopTimer
Times(0) = StopWatch.Interval
Me.Refresh
Call StopWatch.StartTimer ' Profile MoveToEx()/LineTo()
For LoopDraw = 0 To NumDraw - 1
Call MoveToEx(Me.hDC, MyPts(0).X, MyPts(0).Y, ByVal 0&)

For LoopPts = 1 To NumPts - 1
Call LineTo(Me.hDC, MyPts(LoopPts).X, MyPts(LoopPts).Y)
Next LoopPts
Next LoopDraw
Call StopWatch.StopTimer
Times(1) = StopWatch.Interval
Me.Refresh
Set StopWatch = Nothing

' Display results
Call MsgBox( _
"PolyLine(): " & Format$(Times(0), "0.00") & vbCrLf & _
"LineTo(): " & Format$(Times(1), "0.00"))
End Sub








Mike Williams

2006-04-22, 3:56 am

"Jacquelin Hardy" <jachardy@videotron.ca> wrote in message
news:VQf2g.31554$5l2.390411@wagner.videotron.net...

> Is DirectX or OpenGL of any use for speed purposes in a software
> like the one you just wrote Mike ? I am using polypolylgon to display
> about 100,000 points for a vector chart.


I realise that you're addressing the other Mike, but I was just about to
post an addendum to the post I sent a while ago that might (or might not?)
help you. The code that Mike Sutton posted in that specific case seemed to
show that a whole bunch of individual LineTo functions were about twice as
fast as the equivalent PolyLine function. However, when running it I could
see the individual "polyline lines" being drawn. Not all of them
individually of course, but they were definitely not all drawn at once and
there were numerous display updates while the PolyLine was executing. I
considered this to be a bit strange (as I considered the fact that PolyLine
was apparently losing out in the speed stakes to also be a bit strange) so I
decided to see how it would perform if I caused the code to draw into a
memory buffer instead of directly to the Form (by setting Autoredraw to
True). In this specific example it gave a _massive_ increase in speed, and
instead of PolyLine being slower it caused PolyLine to be about
a_hundred_times _faster than the equivalent bunch of LineTo functions. I
still couldn't figure out why PolyLine was apparently causing so many
updates, but I knew of course that doing PolyLine to a memory buffer would
not cause any display updates at all, certainly until the code specifically
caused an update to occur (the Refresh statement) and so the speed was
improved enormously. I then left it at that. However, I came back to it a
few hours later because I just couldn't get out of my head why so many
updates were happening in the "non autoredraw" PolyLine, and I just happened
to delete a Command Button from the test Form (I have a nasty habit of
automatically placing a Command Button on the Form when I start a new
project because I almost invariable use one). Then I noticed that PolyLine
became just as fast on the non autoredraw Form as it was on the Autoredraw
Form (in other words, all of those worrying display updates in the middle of
the PolyLine function execution had ceased to occur). I then realised of
course that it was the "hole in the clipping region" which was causing them
(the hole that no longer existed after I had removed the Command Button).
Further tests showed that a "hole in the clipping region" would cause this
problem even if the hole was nowhere near any of the lines that were being
drawn, so that even if the values were arranged such that only three
quarters of the width of the Form had lines drawn on it and the Command
Button (or whatever) was placed well away from that area the slow down would
still occur. I don't know whether Mike Sutton also had something on his test
Form, or whether there were other reasons for the slow down on his machine,
but such a "a hole in the clipping region" certainly "did PolyLine to death"
on my own machine! So, if you're doing PolyLine to a specific area of the
Form then anything else on that Form (wherever it is) will cause PolyLine to
slow down tremendously (unless you use Autoredraw or a method similar to
Autoredraw of course, in which case it is fine). Therefore, I suggest that
you either use Autoredraw on your Form or alternatively draw your lines into
an otherwise empty Picture Box instead. In that way there will not be any
"holes in the picture box clipping region" and you can have as many controls
as you want in other parts of the Form and you can use the picture box in
Autoredraw or no Autoredraw mode, whichever you prefer.

Anyway, having said that, there is still a little more investigation to be
done I'm afraid. That's because I've just tried your own requirement of
100,000 points (using PolyLine again because that is what I have been
testing with) and the slowdown occurs again, even if there are no holes in
the clipping region :-(

It is obviously the sheer number of points that is doing it, but so far I
have no idea why (although we should be able to figure it out eventually).
It's probably heavily influenced by the memory and the graphics card and its
drivers, but all I can give you of course are the results from my own
system. If there are no holes in the clipping region, or of course if I use
Autoredraw whether there are holes in the clipping region or not, then I can
get PolyLine to draw 1,000 lines in less than one tenth of a millisecond,
which I think you'll admit is quite blindingly fast. I can also get it to
draw 10,000 lines in about a third of a millisecond, which is also
blindingly fast. However, at 20,000 lines (and of course at 100,000 lines)
then it slows down dramatically, because the display updates begin to occur
again. 100,000 lines takes two thousand milliseconds on my machine, which is
a bit like a pig running in treacle! I haven't yet done anything about this,
and I almost certainly won't get time now because I've spent too long on
this already and there are other things to do, but I have an idea that if
you have (say) 100,000 lines to draw then you will be able to get them drawn
pretty quickly if you use 10 separate PolyLine functions to each draw 10,000
of them. As I've said, I haven't had time to test this theory yet, and there
may be other things at play here, but it is definitely worth looking into.

Mike






Mike D Sutton

2006-04-22, 3:56 am

<snip>
> Actually, PolyLine() _is_ faster. It's just that your test code causes
> other things to happen that are not being taken into account. Remember,
> I'm talking about the speed of PolyLine versus the equivalent bunch of
> LineTo calls, and so I'm only interested in the time _those specific
> routines_ take to draw their output, without anything else getting in the
> way of the results. The problem with the code you posted is that a whole
> bunch of display refreshes is going on at the same time, which tends to
> swamp things.


The display is being invalidated and refreshed at just the same rate, if
anything PolyLine() should have the upper hand since it could wait until
it's finished drawing until it invalidates the display but it doesn't appear
to be the case.

> If you use your exact same code but set the Form's Autoredraw property to
> True you will see an entirely different result. Both of them (PolyLine and
> the bunch of LineTo stuff) will of course be very much faster than they
> were before (because we've got the display refreshes out of the way) and
> in addition you'll see that PolyLine is actually very much faster than the
> bunch of LineTo calls. Most people do most of their drawing to offscreen
> buffers anyway, and only dump the result to the screen when it is done, so
> drawing to an offscreen buffer is a perfectly valid way of testing the
> speed of these things. At this end I'm getting a massive speed increase
> all round (as you would of course expect) and I'm seeing PolyLine about _a
> hundred times faster_ than the equivalent bunch of LineTo statements.
> Here's your own code but using Autoredraw = True. Let me know what you get
> at your end.


Oddly enough, enabling AutoRedraw only seems to slow down LineTo() here
while providing no performance increase to PolyLine():
PolyLine(): 3182.70
LineTo(): 2320.58

Without AutoRedraw (i.e. my original code, for comparison):
PolyLine(): 3055.79
LineTo(): 1665.58

If I create a new screen-compatible DDB and DC behind the scenes, and draw
to those rather than touching the form at all:
PolyLine(): 3198.33
LineTo(): 2085.72

Using a 24-bit DIBSection as the back buffer I get:
PolyLine(): 4962.22
LineTo(): 5104.24

16-bit DIBSection:
PolyLine(): 4349.79
LineTo(): 4115.74

And finally a 32-bit DIBSection:
PolyLine(): 5480.77
LineTo(): 5592.94

(All back-buffers were created at 1000*1000)

Why disabling back-buffering should increase the speed of LineTo() and not
PolyLine(), I have no idea but I've gone back and re-tested the results 3
times now and I'm getting consistent measurements.
I am at a loss to explain why on-screen drawing is actually faster than
drawing to a back-buffer though (the timing does _not_ take into account the
blit time to flip this buffer to the screen, this is only the drawing)
I'm running on a 1.9Ghz Dell Inspiron 8200 laptop with 1GB RAM and an nVidia
GeForce Go 440 graphics card, unfortunately I'm in the middle of moving so
it's the only machine accessible in at the moment for comparison testing.

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Mike D Sutton

2006-04-22, 3:56 am

> Is DirectX or OpenGL of any use for speed purposes in a software like the
> one you just wrote Mike ?
> I am using polypolylgon to display about 100,000 points for a vector
> chart.


For the exact application I wrote (I.e. drawing only single-pixel wide lines
and no polygon fills) DirectX is ideal since you can simply specify a vertex
buffer to be rendered as a line list without having to worry about
triangulation etc. This assumes that your dataset does no change too often,
whilst you will still get performance increase pushing the vertex buffer to
the card each frame, it's not quite as efficient as simply pushing it once
and leaving it in graphics card memory.
If you do need to adjust the data, then if you're working with reasonably
simple transformations you may want to look into using vertex shaders to do
that work for you. This means that you simply write the buffer once with no
transformation applied, then manipulate that data on the card through the
use of short applications that are run on the card. The benefit of this is
that you offload the vertex manipulation to the GPU and don't have the CPU
overhead of manipulating the data yourself. The learning curve is slightly
steeper though since you with either have to learn vertex shader
instructions or a high level shader language such as CG or HLSL (You will
also most likely need to use DX9, which is not so easy to call from VB..)
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Mike Williams

2006-04-22, 6:56 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:%23jPg1$eZGHA.428@TK2MSFTNGP02.phx.gbl...

> The display is being invalidated and refreshed at just the same rate


I was talking about being able to see the "currently drawn lines", which of
course doesn't happen if the drawing is going into an offscreen buffer, such
as was the case when I used Autoredraw. Besides, I really didn't expect to
see any individual updates for PolyLine to draw just 1000 lines, because I
expected it to be completed too quickly to visibly identify the different
stages of the drawing, but I could definitely see them plain as day, whereas
I couldn't see any at all for the LineTo drawing. Obviously I was seeing
them simply because PolyLine was taking an unexpected amount of time, about
14,000 milliseconds on my machine for the 100 iterations of the NumDraw
loop, or about 140 milliseconds for the first loop (which of course is the
only one I would see being "built up"). That's about 10 frames on my 75 Hz
display, so of course I could see that happening. In contrast, the LineTo
loop took only 6,000 milliseconds, or 60 milliseconds for the first loop.
That of course is
about 4 frames, which I wasn't quick enough to see (and of course I couldn't
see those at all unless I ran the LineTo loop first, or on its own.
Incidentally, those figures (14,000 and 6,000) are quite abysmal compared to
your own (3,200 and 1,700), even though I'm running a fairly fast processor
and a fairly powerful Radeon 9800 graphics card. Mind you, the processor in
an AMD (3000+) which really only runs at about 2.2 Ghz and the 9800 is the
slightly crippled SE version :-(

> if anything PolyLine() should have the upper hand since it could
> wait until it's finished drawing until it invalidates the display but it
> doesn't appear to be the case.


It certainly didn't have the upper hand on my machine, and apparently also
on yours. However, I just happened to be running your code with a Command
Button on the Form, and it turns out that the "hole in the clipping region"
was slowing things down by a massive amount, certainly much more than I
would have expected. Simply getting rid of the Command Button caused the
same code to run at an amazingly different speed, and then PolyLine most
definitely did have the upper hand. These are the timings I am currently
getting for the full 100 iterations of the "1000 drawn lines":

Standard non-Autoredraw Form with
a Command Button in the middle:
PolyLine: 17300 milliseconds
LineTo: 7060 milliseconds

Exactly the same code on exactly the same
Form but with the Command Button removed:
PolyLine: 2 milliseconds !
LineTo: 206 milliseconds

Both PolyLine and LineTo gain a lot of speed by simply getting rid of the
Command Button (obviously because there is no longer a "hole in the clipping
region"), but the difference in speed of PolyLine is dramatic! Removing the
Command Button from the Form causes the PolyLine code run runs over eight
thousand times faster!

These are the timings I'm getting with Autoredraw set to True:

Autoredraw Form with
a Command Button in the middle:
PolyLine: 2 milliseconds
LineTo: 220 milliseconds

Exactly the same code on exactly the same Autoredraw
Form but with the Command Button removed:
PolyLine: 2 milliseconds
LineTo: 218 milliseconds

As might be expected from the first set of results, Autoredraw gave
approximately the same timings as the "non autoredraw Form" with the Command
button removed, and the timings were the same with or without the Command
Button. This if course was because the autoredraw DC didn't have "a hole in
the clipping region" whether the Command Button was present on the Form or
not.

Further tests proved just as interesting. Drawing to only about 90 per cent
of the Form and with the Command Button still in the middle made no
difference of course in the "non autoredraw test with the Command Button"
and PolyLine still took approximately the same 17000 milliseconds, with
LineTo taking about the same 7000 milliseconds. However, progressively
moving the Command button nearer and nearer the edge of the "drawn area" and
retesting caused PolyLine to remin fixed at about 17000 milliseconds, but
for LineTo to gradually get faster and faster, going down to about 4000,
3000, 2000, 1000 and finally 210 milliseconds as the Command Button was
moved "nearer the edge". PolyLine however remained solid at 17000
milliseconds no matter where the Command Button was, even if just a timy
corner of the Command Button was covering just a single one of the "thousand
points". However, as soon as the Command Button was moved just a couple of
pixels further, so that it was covering none of the thousand points, the
PolyLine timing immediately shot right down from 17000 milliseconds to just
2 milliseconds. Obviously, each of the individual LineTo statements (in the
LineTo code) was checking whether that specific line was partially
underneath the Command Button, and those that weren't were drawn quickly
while those that were under it were drawn slowly. In the case of PolyLine
though, if just a single one of the thousand points was under the Command
Button then every line in the set was drawn slowly. It makes sense I suppose
when you think about it, but it was totally unexpected nonetheless.

> Oddly enough, enabling AutoRedraw only seems to slow down
> LineTo() here while providing no performance increase to PolyLine():
> PolyLine(): 3182.70
> LineTo(): 2320.58


In view of the timings I'm getting that seems very odd indeed. Methinks this
needs a bit more investigation. I'll try it on my laptop later.

Mike



Mike Williams

2006-04-22, 6:56 pm

"Mike Williams" <Mike@WhiskyAndCoke.com> wrote in message
news:%23AhEgphZGHA.1228@TK2MSFTNGP02.phx.gbl...

.. . . by the way, the difference in speed (17000 milliseconds down to 2
milliseonds!) seems to definitely be down to the "lack of a hole in the
clipping region", but the difference is so dramatic that there may be other
thing at play here as well. Probably (although I'm just guessing at the
moment) there is a hardware / software things going on here as well, with
the "no hole in the middle" apparently being done in hardware. Just a guess
at this stage though. But if correct, the results will almost certainly be
affected more by the graphic card than the rest of the machine. I wonder if
anyone else here would care to try your code under the various conditions I
have mentioned to see what they get on their own machines?

Mike




Mike Y

2006-04-22, 6:56 pm


SNIP > I wonder if
> anyone else here would care to try your code under the various conditions

I
> have mentioned to see what they get on their own machines?
>
> Mike
>


No command button
AutoRedraw = True
Polyline: 2636.87/2653.14/2645.04
LineTo: 2753.96/2781.24/2761.94
AutoRedraw = False
Polyline: 1.86/1.87/2.12
LineTo: 74.45/78.38/76.37

Command button on corner
AutoRedraw = True
Polyline: 2652.70/2645.92/2691.87
LineTo: 2787.58/2761.08/2766.10
AutoRedraw = False
Polyline: 2.25/2.28/2.17
LineTo: 574.33/755.94/638.14

Command button in middle
AutoRedraw = True
Polyline: 2673.05/2672.52/2662.55
LineTo: 2798.94/2735.51/2763.39
**********************************
AutoRedraw = False
Polyline: 2.83/10.60/149.25/147.53/10.55/2.92/146.71/2.77/32.11/71.08/2.78
LineTo:
1433.35/1490.46/1281.75/1283.56/1490.82/1471.68/1281.91/1717.99/1639.00/1690
..68/1476.89
****************************************
************************************
***********
Athlon 3200+ Matrox G450


Jacquelin Hardy

2006-04-22, 6:56 pm

Mike Williams,

I tried your code with autoredraw = True and with the 2 refresh. I get
3600 for both LineTo and Polyline.
With Mike D. Sutton code, I get 3.2 for Polylin and 425 for LineTo !
This doesn't agree with your sayings. I suppose there is something wrong
somwhere.

Regards

Jacquelin Hardy


"Mike Williams" <Mike@WhiskyAndCoke.com> a écrit dans le message de news:
u26yHnbZGHA.4884@TK2MSFTNGP02.phx.gbl...
> "Mike D Sutton" <EDais@mvps.org> wrote in message
> news:u1IADOZZGHA.3448@TK2MSFTNGP04.phx.gbl...
>
>
> Hmm, no literature I'm afraid. I usually give far more credence to
> empirical evidence, which is usually the most reliable anyway and which
> tells me that repeatedly calling an API routine to perform a certain task
> is almost always very much slower than calling a similar API routine that
> gets the same job "done in one go".
>
>
> My previous test results were not skewed by anything, although I think
> your own might have been? And yes, I did test before posting, which
> incidentally appears to be more than you did or you would almost certainly
> have noticed the problem with the PolyLine declaration in the code you
> posted, right?..
>
>
> Actually, PolyLine() _is_ faster. It's just that your test code causes
> other things to happen that are not being taken into account. Remember,
> I'm talking about the speed of PolyLine versus the equivalent bunch of
> LineTo calls, and so I'm only interested in the time _those specific
> routines_ take to draw their output, without anything else getting in the
> way of the results. The problem with the code you posted is that a whole
> bunch of display refreshes is going on at the same time, which tends to
> swamp things. If you use your exact same code but set the Form's
> Autoredraw property to True you will see an entirely different result.
> Both of them (PolyLine and the bunch of LineTo stuff) will of course be
> very much faster than they were before (because we've got the display
> refreshes out of the way) and in addition you'll see that PolyLine is
> actually very much faster than the bunch of LineTo calls. Most people do
> most of their drawing to offscreen buffers anyway, and only dump the
> result to the screen when it is done, so drawing to an offscreen buffer is
> a perfectly valid way of testing the speed of these things. At this end
> I'm getting a massive speed increase all round (as you would of course
> expect) and I'm seeing PolyLine about _a hundred times faster_ than the
> equivalent bunch of LineTo statements. Here's your own code but using
> Autoredraw = True. Let me know what you get at your end.
>
> Hope this helps.
>
> Mike
>
> '*** Using: http://edais.mvps.org/Code/Librarie...lsStopWatch.cls
> Private Declare Function MoveToEx Lib "GDI32.dll" (ByVal hDC As Long, _
> ByVal X As Long, ByVal Y As Long, ByRef lpPoint As Any) As Long
> Private Declare Function LineTo Lib "GDI32.dll" (ByVal hDC As Long, _
> ByVal X As Long, ByVal Y As Long) As Long
> Private Declare Function Polyline Lib "GDI32.dll" (ByVal hDC As Long, _
> ByRef lpPoint As PointAPI, ByVal nCount As Long) As Long
>
> Private Type PointAPI
> X As Long
> Y As Long
> End Type
>
> Private Sub Form_Click()
> Me.AutoRedraw = True
> Dim MyPts() As PointAPI
> Dim LoopPts As Long
> Dim StopWatch As clsStopWatch
> Dim LoopDraw As Long
> Dim Times(0 To 1) As Double
>
> Const NumPts As Long = 1000
> Const NumDraw As Long = 100
>
> ' Generate a random polygon
> ReDim MyPts(0 To NumPts - 1) As PointAPI
> For LoopPts = 0 To NumPts - 1
> MyPts(LoopPts).X = Rnd() * 1000
> MyPts(LoopPts).Y = Rnd() * 1000
> Next LoopPts
>
> Set StopWatch = New clsStopWatch
>
> Call StopWatch.StartTimer ' Profile PolyLine()
> For LoopDraw = 0 To NumDraw - 1
> Call Polyline(Me.hDC, MyPts(0), NumPts)
> Next LoopDraw
> Call StopWatch.StopTimer
> Times(0) = StopWatch.Interval
> Me.Refresh
> Call StopWatch.StartTimer ' Profile MoveToEx()/LineTo()
> For LoopDraw = 0 To NumDraw - 1
> Call MoveToEx(Me.hDC, MyPts(0).X, MyPts(0).Y, ByVal 0&)
>
> For LoopPts = 1 To NumPts - 1
> Call LineTo(Me.hDC, MyPts(LoopPts).X, MyPts(LoopPts).Y)
> Next LoopPts
> Next LoopDraw
> Call StopWatch.StopTimer
> Times(1) = StopWatch.Interval
> Me.Refresh
> Set StopWatch = Nothing
>
> ' Display results
> Call MsgBox( _
> "PolyLine(): " & Format$(Times(0), "0.00") & vbCrLf & _
> "LineTo(): " & Format$(Times(1), "0.00"))
> End Sub
>
>
>
>
>
>
>
>



Ralph

2006-04-22, 6:56 pm


"Mike Williams" <mike@WhiskyAndCoke.com> wrote in message
news:OtlYH%23hZGHA.1348@TK2MSFTNGP05.phx.gbl...
> "Mike Williams" <Mike@WhiskyAndCoke.com> wrote in message
> news:%23AhEgphZGHA.1228@TK2MSFTNGP02.phx.gbl...
>
> . . . by the way, the difference in speed (17000 milliseconds down to 2
> milliseonds!) seems to definitely be down to the "lack of a hole in the
> clipping region", but the difference is so dramatic that there may be

other
> thing at play here as well. Probably (although I'm just guessing at the
> moment) there is a hardware / software things going on here as well, with
> the "no hole in the middle" apparently being done in hardware. Just a

guess
> at this stage though. But if correct, the results will almost certainly be
> affected more by the graphic card than the rest of the machine. I wonder

if
> anyone else here would care to try your code under the various conditions

I
> have mentioned to see what they get on their own machines?
>
> Mike
>


Here are the results on a slower machine:
1.67 gigahertz AMD Athlon XP
NVIDIA GeForce FX 5200

No Command Buton:
AutoDraw = True
PolyLine(): 2.62, 2.64, 2.55
LineTo(): 1327.70, 1354.30, 1359.49
AutoDraw = False
PolyLine(): 2.45, 2.62, 2.54
LineTo(): 97.22, 96.66, 100.14

Command button on corner:
AutoRedraw = True
PolyLine(): 2.69, 2.57, 2.63
LineTo(): 1466.80, 1355.84, 1359.64
AutoDraw = False
PolyLine(): 3.06, 3.11, 3.06
LineTo(): 98.11, 99.90, 100.12

Command Button in the Middle:
AutoDraw = True
PolyLine(): 2.61. 2.55, 2.48
LineTo(): 1327.70, 1354.52, 1359.56
AutoDraw = False
PolyLine(): 17.81, 21.49, 20.34
LineTo(): 102.66, 107.55, 105.00


Jacquelin Hardy

2006-04-22, 6:56 pm

I tried both codes, with and without a command button on the form.

My results:

M. D.Sutton code :

no Command button with a command
button
PolyLine 3.25
29075
Line To 460
6000

Mike Williams code (with Autoredraw=True and 2 refresh
no Command button with a command
button
PolyLine 3600
3600
Line To 3750
3570

Nothing is faster than M.D. Sutton code without a commandbutton.
I have a Pentium 4 - 2.9 Mhz and a Radeon 9600 card.

JH

"Mike Williams" <mike@WhiskyAndCoke.com> a écrit dans le message de news:
OtlYH%23hZGHA.1348@TK2MSFTNGP05.phx.gbl...
> "Mike Williams" <Mike@WhiskyAndCoke.com> wrote in message
> news:%23AhEgphZGHA.1228@TK2MSFTNGP02.phx.gbl...
>
> . . . by the way, the difference in speed (17000 milliseconds down to 2
> milliseonds!) seems to definitely be down to the "lack of a hole in the
> clipping region", but the difference is so dramatic that there may be
> other thing at play here as well. Probably (although I'm just guessing at
> the moment) there is a hardware / software things going on here as well,
> with the "no hole in the middle" apparently being done in hardware. Just a
> guess at this stage though. But if correct, the results will almost
> certainly be affected more by the graphic card than the rest of the
> machine. I wonder if anyone else here would care to try your code under
> the various conditions I have mentioned to see what they get on their own
> machines?
>
> Mike
>
>
>
>



Mike Williams

2006-04-22, 6:56 pm

"Jacquelin Hardy" <jachardy@videotron.ca> wrote in message
news:65t2g.32897$U%4.535791@weber.videotron.net...

> I tried your code with autoredraw = True and with the 2 refresh. I get
> 3600 for both LineTo and Polyline.
> With Mike D. Sutton code, I get 3.2 for Polylin and 425 for LineTo !
> This doesn't agree with your sayings. I suppose there is something wrong
> somwhere.


Actually it's all Mike Sutton's code, in all cases. I just added and / or
removed things like Autoredraw and Command buttons and stuff to test it
under different conditions. Your 3.2 for PolyLine and 425 for LineTo agrees
fairly well with what I'm getting here, at least with respect to PolyLine
being very much faster than LineTo except under certain very specific
conditions. But in either case you haven't said what conditions you are
running your code under (autoredraw, command button or not, etc) so I can't
see anything from it without that information. Any chance you can try the
tests again and come back with some full details?

Mike


Jacquelin Hardy

2006-04-22, 6:56 pm

Correction on my last to display results:

M. D.Sutton code, no command button : polyLine 3.25, Line To 460
M. D.Sutton code, with cmdbutton : PolyLine 9000, Line To 91

Mike Williams code, no command button : polyLine 3600, Line To 3700
Mike Williams code, with cmdbutton : PolyLine 3600, Line To 3700

Sorry about the mistakes.

With M. Williams, no difference with or without a command button. With
M.D.Sutton code, a big difference !

JH



"Jacquelin Hardy" <jachardy@videotron.ca> a écrit dans le message de news:
Lzu2g.34581$U%4.565877@weber.videotron.net...
>I tried both codes, with and without a command button on the form.
>
> My results:
>
> M. D.Sutton code :
>
> no Command button with a command
> button
> PolyLine 3.25 29075
> Line To 460 6000
>
> Mike Williams code (with Autoredraw=True and 2 refresh
> no Command button with a command
> button
> PolyLine 3600 3600
> Line To 3750 3570
>
> Nothing is faster than M.D. Sutton code without a commandbutton.
> I have a Pentium 4 - 2.9 Mhz and a Radeon 9600 card.
>
> JH



Mike Williams

2006-04-22, 6:56 pm

"Jacquelin Hardy" <jachardy@videotron.ca> wrote in message
news:Lzu2g.34581$U%4.565877@weber.videotron.net...

> My results:
> M. D.Sutton code :
> Mike Williams code


I wish you'd stop saying "Mike Sutton's code" and "Mike Williams' Code".
It's all mike Sutton's code. At this end I'm just running Mike Sutton's code
with and without Autoredraw and with and without a Command Button in the
middle and I'm just trying to get a picture of the speeds on various
machines, hopefully with people sayng what sort of machine they have and
what graphics card s fitted. The results so far vary wildly from one machine
to the next.

For example, with Autoredraw = True (the one I expect you are calling "Mike
Williams code") we so far have the following results for PolyLine (in whole
milliseconds). In all cases they are about the same with or without the
Command Button (as you would of course expect):

PolyLine (1000 points, 100 loops) Autoredraw True
3182 milliseconds (Mike Sutton 1.9 Ghz laptop, Geforce GO 440)
2 milliseconds (Mike Williams AMD 3000+, Radeon 9800 SE))
2600 milliseconds (Mike Y AMD 3200+, Matrox G450)
3 milliseconds (Ralph AMD 1.6 Ghz, Geforce FX 5200)
3600 milliseconds (Jacquelin Hardy P4 2.9 Ghz, Radeon 9600)

These are wildly different results, with three of them in the "pig in
treacle"range and the other two going like "shit off a shovel"! Hopefully
we'll get some more results later (I'll be testing my laptop out later
tonight probably).

Here's what we seem to have so far for the non - autoredraw Form (the one I
expect you are calling Mike Sutton's code):

PolyLine (1000 ponts, 100 loops) Autoredraw False, Command Button
3055 milliseconds (Mike Sutton 1.9 Ghz laptop, Geforce GO 440)
17300 milliseconds (Mike Williams AMD 3000+, Radeon 9800 SE))
52 milliseconds avg (Mike Y AMD 3200+, Matrox G450)
20 milliseconds avg (Ralph AMD 1.6 Ghz, Geforce FX 5200)
9000 milliseconds (Jacquelin Hardy P4 2.9 Ghz, Radeon 9600)

Again, wildly different results with three again in the "pig in treacle"
mode (but not the same three) and two in the "shit off a shovel" mode! And
the there are:

PolyLine (1000 ponts, 100 loops) Autoredraw False, No Command Button
3055 milliseconds (Mike Sutton 1.9 Ghz laptop, Geforce GO 440)
2 milliseconds (Mike Williams AMD 3000+, Radeon 9800 SE))
2 milliseconds avg (Mike Y AMD 3200+, Matrox G450)
3 milliseconds avg (Ralph AMD 1.6 Ghz, Geforce FX 5200)
3 milliseconds (Jacquelin Hardy P4 2.9 Ghz, Radeon 9600)

Here we have only ne in the "pig in treacle" mode, with the other four going
like "shit off a shovel". The only proviso at the moment is that Mike
Suttons hasn't mentioned whether his timings were with a Command Button or
not, so we're not quite sure.

There isn't a lot definite we can say about the results so far, unless we
have some more timings from Mike Sutton saying whether they were "Command
Button on the Form" or not, and perhaps other timings might come in from
others later. At the moment its a bit too early to draw any general
conculsions that will hold good for all systems, and perhaps we may never be
able to do so, except perhaps that it would be wise to avoid drawing into
DCs that have "holes in the clipping region" if you want to be in with the
best chance of running at a decent speed. So far, as has often been the case
when dealing with graphics, there are just too many variables to draw hard
and fast conclusions as far as the API routines are concerned and the best
you can do is write code that "is likely to run fast on most machines", with
no guarantees that it will not run like a pig in treacle on some :-(

Anyway, I expect people are getting fed up with this thread by now. Time for
a rum and Coke® methinks ;-)

Mike



Mike Williams

2006-04-25, 6:57 pm

"Ralph" <nt_consulting64@yahoo.com> wrote in message
news:cJ-dnfCFI5a-79fZnZ2dnUVZ_sGdnZ2d@arkansas.net...

> Here are the results on a slower machine:
> 1.67 gigahertz AMD Athlon XP NVIDIA GeForce FX 5200


> AutoDraw = True Command Button in middle
> PolyLine(): 2.6 LineTo(): 1327.0
> AutoDraw = False No Button
> PolyLine(): 2.4 LineTo(): 97.2
> [some results snipped for brevity]


Thanks Ralph (and others). I think a pattern is begining to emerge now. I've
just tried the code on my laptop (XP PentiumM 1.7 Ghz Radeon 9700 mobility
graphics card) and I get the following:

AutoDraw = True Command Button in middle
PolyLine(): 7.8 LineTo(): 986.2

AutoDraw = False No Button
PolyLine(): 7.4 LineTo(): 823.8

If you recall, this thread kicked off when I said that a call to the
PolyLine API was much faster than the equivalent number of individual calls
to the LineTo API, and Mike Sutton said that he could not achieve such a
result on his own machine and that he was getting the opposite result.
Looking at the various answers that have come in it appears that I was
correct, and that PolyLine is fairly consistent on all machines at about a
hundred times faster than the equivalent bunch of LineTo calls (for the
example posted), except in just one case at the moment, which I'll mention
later. However, for PolyLine to achieve such a fast speed and for it to be
more or less guaranteed on most systems you need to be drawing to the
displayed Form or Picture Box directly (ie not to a backbuffer) and there
needs to be no "holes" in the clipping region (ie, no Command Buttons or
anything else over any part of the area onto which the drawing is taking
place). This "hole in the clipping region" definitely seems to be the thing
that slows down PolyLine, because the slow down occurs whether the object in
the way is part of your VB project or not. For example, placing even a very
small "always on top" window of another app in the drawing area will produce
the same slow down, for exactly the same reason. The object has this effect
even if it covers only a single pixel of the complete line drawing. Some
people (myself and a few others) are also getting extremely fast results
from PolyLine when drawing to a backbuffer as well, but others are not doing
so, so it looks like drawing to the displayed Form or Picture Box is the
best option if you want more or less guaranteed speed.

There are six or seven sets of results in so far (including my own laptop
results above) and all of them except one are getting a time of just a few
milliseconds for the "direct to Form with no Command Button" PolyLine test,
which is very fast (100 iterations each drawing 1000 lines). The only person
who isn't getting that result so far is Mike Sutton, who is getting 3055
milliseconds, a massive difference. I'm beginning to wonder wheher Mike
Sutton actually does have something in the drawing area (perhaps an "on top"
results window or something), but I'm sure he'll say so if he has. I'm also
beginning to think that maybe "1000 lines at a time" might be just too many
for some machines, and if Mike might get a better result by splitting the
"1000 point" PolyLine into perhaps 5 separate "200 point" polylines? And
maybe the original poster (Jacquelin) might also get faster performance with
her PolyPolygon drawing of 100,000 polygons (I think she said) if she did
something similar and split the 100,000 polygons into perhaps a hundred sets
each of 1000 polygons, or perhaps even five hundred sets of 200 polygons.
Perhaps you might like to try that, Jacqueline? It certainly can't do any
harm to try. Also, draw into the displayed Form or Picture Box and make sure
nothing is in "on top" in the drawing area.

Mike





Mike D Sutton

2006-04-25, 6:57 pm

> Thanks Ralph (and others). I think a pattern is begining to emerge now.
> I've just tried the code on my laptop (XP PentiumM 1.7 Ghz Radeon 9700
> mobility graphics card) and I get the following:
>
> AutoDraw = True Command Button in middle
> PolyLine(): 7.8 LineTo(): 986.2
>
> AutoDraw = False No Button
> PolyLine(): 7.4 LineTo(): 823.8
>
> If you recall, this thread kicked off when I said that a call to the
> PolyLine API was much faster than the equivalent number of individual
> calls to the LineTo API, and Mike Sutton said that he could not achieve
> such a result on his own machine and that he was getting the opposite
> result. Looking at the various answers that have come in it appears that I
> was correct, and that PolyLine is fairly consistent on all machines at
> about a hundred times faster than the equivalent bunch of LineTo calls
> (for the example posted), except in just one case at the moment, which
> I'll mention later. However, for PolyLine to achieve such a fast speed and
> for it to be more or less guaranteed on most systems you need to be
> drawing to the displayed Form or Picture Box directly (ie not to a
> backbuffer) and there needs to be no "holes" in the clipping region (ie,
> no Command Buttons or anything else over any part of the area onto which
> the drawing is taking place). This "hole in the clipping region"
> definitely seems to be the thing that slows down PolyLine, because the
> slow down occurs whether the object in the way is part of your VB project
> or not. For example, placing even a very small "always on top" window of
> another app in the drawing area will produce the same slow down, for
> exactly the same reason. The object has this effect even if it covers only
> a single pixel of the complete line drawing. Some people (myself and a few
> others) are also getting extremely fast results from PolyLine when drawing
> to a backbuffer as well, but others are not doing so, so it looks like
> drawing to the displayed Form or Picture Box is the best option if you
> want more or less guaranteed speed.
>
> There are six or seven sets of results in so far (including my own laptop
> results above) and all of them except one are getting a time of just a few
> milliseconds for the "direct to Form with no Command Button" PolyLine
> test, which is very fast (100 iterations each drawing 1000 lines). The
> only person who isn't getting that result so far is Mike Sutton, who is
> getting 3055 milliseconds, a massive difference. I'm beginning to wonder
> wheher Mike Sutton actually does have something in the drawing area
> (perhaps an "on top" results window or something), but I'm sure he'll say
> so if he has. I'm also beginning to think that maybe "1000 lines at a
> time" might be just too many for some machines, and if Mike might get a
> better result by splitting the "1000 point" PolyLine into perhaps 5
> separate "200 point" polylines? And maybe the original poster (Jacquelin)
> might also get faster performance with her PolyPolygon drawing of 100,000
> polygons (I think she said) if she did something similar and split the
> 100,000 polygons into perhaps a hundred sets each of 1000 polygons, or
> perhaps even five hundred sets of 200 polygons. Perhaps you might like to
> try that, Jacqueline? It certainly can't do any harm to try. Also, draw
> into the displayed Form or Picture Box and make sure nothing is in "on
> top" in the drawing area.


Sorry for the delay in response, been busy for the last few days.
In answer to your queries from various posts in this thread, I didn't have
any controls on the form (the code was kicked off from the MouseDown() event
handler so there was no need.) and there were no always-on-top windows
visible at the time the results were taken. In any case, neither controls
or AOT windows would affect performance of drawing to a back-buffer.
Dropping the point count to 200 and upping the draw count to 500 (same
number of points, smaller lines) gives pretty much identical results to my
original performance stats in that I'm seeing LineTo() perform nearly twice
as fast as PolyLine().
Unfortunately I still don't have my other machines properly set up to test
on, the only one I did test on was my monitorless server via VNC, but the
test results were horribly skewed since VNC monitors all GDI calls. The
test results there were roughly 4 seconds for PolyLine() and 8 for LineTo(),
however how much of this was down to the overhead of VNC I couldn't say.
I should be back on my primary dev. machine later in the w and I'll post
the results from there.
Cheers,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Mike Williams

2006-04-25, 6:57 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:u25Z%23q4ZGHA.1192@TK2MSFTNGP04.phx.gbl...

> In any case, neither controls or AOT windows would
> affect performance of drawing to a back-buffer.


Yes. I agree. That is why in my own tests on my own machine I was getting a
very fast timing (just a few milliseconds) when Autoredraw was True whether
there were buttons on the Form or not. But I was also getting a very fast
timing (again just a few milliseconds) on the non Autoredraw drawing when
there were no Buttons or other things in the drawing area, but very slow
results when there were, whereas on your own machine you were not getting
similar results at all and all drawings were very slow under all
circumstances.

> . . . the only one I did test on was my monitorless server via
> VNC, but the test results were horribly skewed since VNC
> monitors all GDI calls. The test results there were roughly
> 4 seconds for PolyLine() and 8 for LineTo()


Right. I didn't know that you were using a monitorless server. I would think
that's almost certainly the reason your test is running so slowly.

> I should be back on my primary dev. machine later
> in the w and I'll post the results from there.


Thanks Mike. I imagine that you'll then see a _massive_ increase in the
speed of PolyLine. I'd also of course be interested in seeing what effects a
"Command Button in the drawing area" has on the "non Autoredraw" drawing
speed, and also whether you then get similar result to my own, where drawing
to an Autoredraw buffer is just a few milliseconds as well.

Cheers

Mike




Mike D Sutton

2006-04-25, 6:57 pm

> Right. I didn't know that you were using a monitorless server. I would
> think that's almost certainly the reason your test is running so slowly.


Just to clarify, all the other results were run on my dev. laptop without
VNC or any other display mirroring driver running that may obscure the
results, PolyLine() is just performing very slowly for some reason on this
machine!

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Mike D Sutton

2006-04-25, 6:57 pm

> Is DirectX or OpenGL of any use for speed purposes in a software like the
> one you just wrote Mike ?
> I am using polypolylgon to display about 100,000 points for a vector
> chart.


Apologies for this thread getting heavily sidetracked, it quite often
happens here!
Getting back to the original question, what kinds of polygons are you trying
to draw? Are they filled (flat colour/pattern/texture/gradient)? Do you
need to draw the edges, and if so are they single pixel or wide lines? Do
you have lots of very simple polygons or just one very large polygon with
thousands of points? Do they have holes or self-intersect? I.e. consider
the letter "O", it's made up of two polygons but the inner one cuts a hole
in the first one to make the hole in the middle. Self intersection is where
a polygons edge crosses itself such as if you had the 4 points of a square
numbered 1 to 4 clockwise, and drew the line 1, 2, 4, 3, 1 - You would get
what looked like two triangles pointing at each other.
How often does the data change, i.e. are you drawing an animated morph of
the polygon or is it just static? If it does move then how does it move,
does the number of points stay the same or is the polygon completely
different between frames?
The more information you give us, the better recommendations we can give you
for the best quality performance.
Cheers,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Ralph

2006-04-25, 6:57 pm


"Jacquelin Hardy" <jachardy@videotron.ca> wrote in message
news:Fr72g.30120$5l2.299724@wagner.videotron.net...
> Hello group,
>
> I wrote a marine software with vector charts. The charts are made of
> polygons, lines and points. Polygons and lines each have a bounding box to
> determine if they are in the viewing screen or not.
>
> My question is: would I gain in speed display by using DirectX or OpenGL
> rather than VB6 alone and some APIs like Polypolygon ?
>
> Thank you
>
> Jacquelin Hardy
>


Do you see now why I sit back and let the experts go at it? <g>

Again, the real secret is to adopt "A" drawing tool and stick with it. Then
test, test, test. Results will be determined primarily by subtle changes in
the architecture, and just like games - the amount of RAM and the Graphics
card. Any of the libraries will likely do a decent job on a modern box.

Try and avoid pre-optimizing. That is, spending too much time up front,
guessing where the bottle-necks might be. Design your app logically, make it
work, then test, then tweak... As Bruce McKinney re-quoted - "It doesn't
matter how fast it is, if it doesn't work". <g>

-ralph


Mike Williams

2006-04-25, 6:57 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:%23hJJxQ6ZGHA.3684@TK2MSFTNGP05.phx.gbl...

> Just to clarify, all the other results were run on my dev. laptop
> without VNC or any other display mirroring driver running that
> may obscure the results, PolyLine() is just performing very
> slowly for some reason on this machine!


Weird that, Mike. It's hard to believe that you're getting three seconds or
more for PolyLine direct to the non Autoredraw Form (with no Command Button
or anything in the drawing area) when it seems that all of the people who
responded (seven of them I think, if you count machines rather than people,
including the original poster) are getting something in the region of two or
three milliseconds under the same conditions. That's a thousand fold
increase! I don't really know how the Windows GDI handles the available
accelerated hardware functions on graphics cards, but offhand I'd say that
for such a massive speed difference it must be down to the fact that Windows
does actually use the graphics card functions when they are available, even
when using the standard API routines, and that perhaps your own graphics
card does not provide PolyLine in hardware whereas all the others do? That
is the only thing I can think of to explain why PolyLine should actually be
slower than numerous separate calls to the LineTo API. In fact I had started
to think that perhaps the reason PolyLine works so quickly (on all machines
except your own at the moment) when there is no "hole in the clipping
region", and so very slowly on the very same machines when there is, might
be because Windows can use the hardware PolyLine function when there is no
"hole in the clipping region" but has to do it in software when there is?

Perhaps you're getting the extremely slow PolyLine stuff on your own laptop
machine under both conditions because PolyLine might not be provided in
hardware on your machine, whereas LineTo might be? I must admit that I'm a
bit (a lot!) at the moment. Have you checked your card's
accelerated functions in Control Panel? As you know there are various
different safety settings. Perhaps yours is set to a "safe but slow" none or
limited hardware acceleration setting? Bit weird all this, and I'd really
like to drop the thread because others are probably getting well fed up of
it by now, but I'm like a little dog with a bone at the moment :-)

Mike


Mike Williams

2006-04-25, 6:57 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:%23UK2tV6ZGHA.4424@TK2MSFTNGP05.phx.gbl...

I think I might be getting somewhere with this PolyLine stuff, Mike (Mike
Sutton), but I'm not sure yet. I know that I said earlier that it might be
down to a difference between "hardware drawing" and "software drawing" (and
I still stand by that), but even that would not account for the
_massive_difference in apparent speed (a thousand fold) between the two that
we are seeing, so I've been doing a little more "digging around". I've just
performed a few tests on my laptop and I'm getting something that I've
noticed many times before for all sorts of graphics drawing tests I've done,
and that it the fact that under certain conditions and for certain drawing
operation the "time to complete the drawing code" is often very much less
than the time the system takes to actually complete the drawing. I've always
in the past put this down to the fact that some drawing operations are
simply "passed to the video card driver" for completion and the VB code
itself them comes away, leaving the graphics card and / or its driver to get
on with the actual drawing job. It's beginning to look as though that
assumption of mine is actually correct.

I tried a slightly simplified version of the code you posted (without using
the Timer Class so that others might be more easily persuaded to try it) and
in my specific test I noticed that even though the "reported time" was just
7 milliseconds or less, the "time for the system to actually complete the
set of drawings" was quite a bit more (although still nothing like the three
seconds or more that you are getting). I deduced the "time for the system to
complete the drawing" time by addng a line of code to draw some text into
the Form's caption. If there were drawings "still queued in the graphics
card" then of course such a "caption drawing" would have to wait its turn,
and would not be completed until the main previously triggered set of
polyline drawings to the Form were completed. I supplemented this by drawing
a red circle onto the Form at the end of the PolyLine stuff, and the red
circle appeared at exactly the same time as the Caption change. On my laptop
I got a reported time of just 7 milliseconds for the "time to draw all the
PolyLines", indicating that the olyline code had all been executed and that
the "t2 = timeGetTime" line of code was executed after just 7 milliseconds,
but the "red circle" and the change in the Form's caption did not actually
appear until after about half a second later (quite a considerable time in
relation to 7 milliseconds), indicating that although the VB code had
finished after 7 milliseconds, and the processor was free to get on with any
other jobs that needed doing, the video card had not finished at all, and in
fact neded a further 500 or so milliseconds to complete the drawing job. Now
that seems to make sense to me, and I would believe that half a second "
hardware" would equate to the "three or four seconds in software" that you
(Mike Sutton) appear to be seeing on your own machine. I have known for some
time that it is not wise to trust "reported timings" from code that is
running graphics commands, but for some reason I didn't think of taking this
stuff into account in this specific case. (Is everyone suitably bored yet?).
I haven't yet tried this code on my main desktop machine, but I'll let you
know what results I get when I have done so.

At the risk of alienating everyone here who might have become bored with
this thread I would like to invite everyone to help in a little test. Those
of you who have been following this thread will already know what it is all
about, but for those who haven't it is simply a little test to check the
speed of various drawing operations under various different conditions. I'd
appreciate it if you would kindly paste the following code into a VB Form
and run the program. Then click the Form and see what time is reported for
the finished drawing (in the Caption bar). At the same time carefully watch
the Form to see when the red circle appears, and when the caption changes.
Do these times appear to agree. For example, if you wait about half a second
or so (500 milliseconds or so) for the red circle and the change in caption
to appear and yet the caption bar shows a time that is significantly less
than 500 milliseconds?

Ty the test a few times and note the results. Then add a Command Button
somewhee in the centre of the Form and try the test again.

I would appreciate it if you would kindy post the results, saying what
machine you have and what graphics card you are using. Even Michael C could
help in this one. He's been unusually absent from this thread since it
started, and I'm beginning to wonder if he has tried the previous tests and
found they agree roughly with what I have been saying and has decided not to
post his results just because he would prefer not to say anything that might
indicate he agrees with me on something ;-)

I've put the code in the Form's MouseDown event, so that it runs as soon as
you press h left moyse button down.

Mike

p.s. Anybody bored yet ;-)

Oops! Nearly forgot the code. here it is:


Private Declare Function Polyline Lib "GDI32.dll" (ByVal hDC As Long, _
ByRef lpPoint As PointAPI, ByVal nCount As Long) As Long
Private Type PointAPI
X As Long
Y As Long
End Type
Private Declare Function timeGetTime Lib "winmm.dll" () _
As Long
Private Declare Function timeEndPeriod Lib "winmm.dll" _
(ByVal uPeriod As Long) As Long
Private Declare Function timeBeginPeriod Lib "winmm.dll" _
(ByVal uPeriod As Long) As Long

Private Sub Form_Load()
Me.WindowState = vbMaximized
Me.ScaleMode = vbPixels
timeBeginPeriod 1
Caption = "please click the Form . . ."
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single,
Y As Single)
Me.Cls
Caption = "Please wait . . "
Me.AutoRedraw = False
Dim t1 As Long, t2 As Long
Dim MyPts() As PointAPI
Dim LoopPts As Long
Dim LoopDraw As Long
Const NumPts As Long = 1000
Const NumDraw As Long = 100

' Generate a random polygon
ReDim MyPts(0 To NumPts - 1) As PointAPI
For LoopPts = 0 To NumPts - 1
MyPts(LoopPts).X = Rnd() * Me.ScaleWidth
MyPts(LoopPts).Y = Rnd() * Me.ScaleHeight
Next LoopPts
t1 = timeGetTime
For LoopDraw = 0 To NumDraw - 1
Call Polyline(Me.hDC, MyPts(0), NumPts)
Next LoopDraw
t2 = timeGetTime
Me.Circle (100, 100), 100, vbRed
Caption = Format(t2 - t1) & " milliseconds."
Caption = Caption & " Please click again . . ."
End Sub

Private Sub Form_Unload(Cancel As Integer)
timeEndPeriod 1
End Sub









Mike D Sutton

2006-04-25, 6:57 pm

I'm getting 4085 here on the laptop. Red circle and caption change appear
simultaneous.

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Jacquelin Hardy

2006-04-25, 6:57 pm

Mike,

I will try to answer as accurately as possible to your questions.

My electronic vector chart represents an area of 70 nautical miles of the
Saint-Lawrence river (Canada). This area is divided in 3 sectors of 24 miles
or so. One polygon file, one line file and one points file for each sector.

I start by a test to find out in which sector I am. Each polygon file (700K)
is made of 300 or so polygons with many having holes. On the file they are
stored with latitude and longitude x 1 million (to use long variables). The
largest polygons have 10,000 points, the smalllest 4.

Each point is compared to a reference point, at a certain scale, and X and Y
are then obtained in pixels.

The holes do not intersect. Polygons are filled with flat colors. Edges are
drawn. Some with 2 pixels wide, most with one only. The data changes every
minute or so, to display an area in front of a moving ship and every time
the user changes the scale, then the chart is redrawn. Everything is static
except the shape of a ship moving along its track.

Polygons never change shape, only the size changes, along with the chosen
scale.

Et voilà !

JH

"Mike D Sutton" <EDais@mvps.org> a écrit dans le message de news:
%23UK2tV6ZGHA.4424@TK2MSFTNGP05.phx.gbl...
>
> Apologies for this thread getting heavily sidetracked, it quite often
> happens here!
> Getting back to the original question, what kinds of polygons are you
> trying to draw? Are they filled (flat colour/pattern/texture/gradient)?
> Do you need to draw the edges, and if so are they single pixel or wide
> lines? Do you have lots of very simple polygons or just one very large
> polygon with thousands of points? Do they have holes or self-intersect?
> I.e. consider the letter "O", it's made up of two polygons but the inner
> one cuts a hole in the first one to make the hole in the middle. Self
> intersection is where a polygons edge crosses itself such as if you had
> the 4 points of a square numbered 1 to 4 clockwise, and drew the line 1,
> 2, 4, 3, 1 - You would get what looked like two triangles pointing at each
> other.
> How often does the data change, i.e. are you drawing an animated morph of
> the polygon or is it just static? If it does move then how does it move,
> does the number of points stay the same or is the polygon completely
> different between frames?
> The more information you give us, the better recommendations we can give
> you for the best quality performance.
> Cheers,
>
> Mike
>
>
> - Microsoft Visual Basic MVP -
> E-Mail: EDais@mvps.org
> WWW: Http://EDais.mvps.org/
>



Mike Williams

2006-04-25, 6:57 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:%23%23v8JE$ZGHA.3524@TK2MSFTNGP04.phx.gbl...

> I'm getting 4085 here on the laptop. Red circle
> and caption change appear simultaneous.


I'm getting just 7 on my laptop here. Red circle and caption both appear
together, but not until about 500 milliseconds (as far as I can tell with a
stopwatch) have elapsed. So, on my laptop the VB code finishes executing
after just 7 milliseconds but the final result (the red circle) does not
appear until a further 600 milliseconds have elapsed. Both a lot faster than
on yours, but the 7 is so fast that it is actually unelievable. There are
100,000 lines altogether, and there is no way I think even in hardware that
a singe line of something like 500 pixels in length on average can be
calculated and drawn in just 7 nanoseconds. So (as is evidenced by the 500
millisecond delay) there has got to be a queue in operation somewhere, with
the PolyLine API simply placing the desired drawng into that queue. Maybe
it's not a queue in hardware though as I at first thought. Maybe it's just
PolyLine sending its request to the GDI and coming away immediately,
allowing the GDI to get on with the actual drawing job without hindering the
operatio of the rest of the VB code. In fact I've just tried a further
little test and changed to loop iterations from 100 to 1000 (so we're
drawing ten times as many polylines as before) and this time I get a
displayed time of about 4400, with the red circle appearing at apparently
the same time. So, if you believe the actual timed results which time how
long the VB code takes to execute you would believe that a total of 100,000
lines takes just 7 milliseconds todraw whereas a total of 1000,000 lines
(ten times as many) take 4400 milliseconds (more than 600 hundred times as
long). But, and this is the interesting bit, if you time it *very carefully*
with an accurate stop watch you can see that when the "timed result" is
displayed as 4400 millisconds the time for the red circle to appear s
something lik a full five seconds (5000 milliseconds). So, my thoughts so
far are that a queue is indeed involved, but that bthere is a limit as to
how many dawing operatins can be stored in that queue. That would explain
why my first test (100 loop iterations) displayed 7 but actually took about
500, and why my secod test (1000 loop iterations) displayed 4400 but took
something like 5000.

I think one day I might rig up a sensor over the screen so that I can get a
better idea of what is actually happening. At least I should enable me to
tell when the red circle appears to within about ten or twenty milliseconds
or so.

Or, alternatively, I might just open another bottle of red wine ;-)

Mike



Mike D Sutton

2006-04-25, 6:57 pm

<snip>
> I think one day I might rig up a sensor over the screen so that I can get
> a better idea of what is actually happening. At least I should enable me
> to tell when the red circle appears to within about ten or twenty
> milliseconds or so.


You have _way_ too much free time on your hands!
I'd doubt it would make any difference since it's generally only used in
multi-threaded drawing, but if it really is drawing asynchronously then you
may find that the GDIFlush() API call after performing your drawing will
give more accurate results.
I find it a bit hard to believe that this would be the case though even if
it's hardware accelerated, since asynchronous drawing could cause all kinds
of problems for many applications relying on GDI to draw in a certain order.
Cheers,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Mike Williams

2006-04-25, 6:57 pm

"Mike D Sutton" <EDais@mvps.org> wrote in message
news:eh8npdGaGHA.4292@TK2MSFTNGP02.phx.gbl...

> I'd doubt it would make any difference since it's generally
> only used in multi-threaded drawing, but if it really is drawing
> asynchronously then you may find that the GDIFlush() API
> call after performing your drawing will give more accurate results.


Actually you're quite right when you say GDIFlush will make no difference,
because it doesn't! I still get a "timed period" of just 7 milliseconds for
the entire loop (100 iterations of a 1000 line PolyLine). In fact I can even
put the GDIFlush inside the "100 iteration" loop (rather than at the end of
it) and it still makes no difference. Also, this morning I came to an answer
taking into account just one iteration), but now I can see that if the
"timed result" is correct and actually indicates that the entire set of
drawings has been completed then I'm getting 100 x 1000 = 100,000 lines in
just 7 milliseconds! The instant I click the button the time appears, and
the beep occurs (I've put a beep in now!). On average the length of each
individual line will be something in the region of 500 pixels and if the
time is correct then it means a single line of 500 pixels is being
calculated and drawn in just 70 picoseconds! I know Ive got a reasonably
fast laptop, but I'm not havin' that ;-)

I amended the code a bit so as to include a Beep and so as to draw the last
of the 100 PolyLine drawings in red (rather than black). This is an extract:

Call StopWatch.StartTimer
Me.ForeColor = vbBlack
For LoopDraw = 0 To NumDraw - 1
If LoopDraw = (NumDraw - 1) Then
Me.ForeColor = vbRed
End If
Call Polyline(Me.hDC, MyPts(0), NumPts)
Next LoopDraw
GdiFlush
Call StopWatch.StopTimer
Times(0) = StopWatch.Interval
Beep
Caption = Format$(Times(0))

Whe I run the code with the above modifications I get the "beep" and the
first set of "1000 black lines" both at the same time, and both of them
occur the instant I click the mouse button. However, the final set of "1000
red lnes" des not appea on the Form for about another half a secnd, and at
the same time they appear the time is displayed in the Caption bar. The time
is 7 milliseconds, and it must be correct as far as your timer code is
concerned because, as I've said, the "beep" occurs immediately I click the
button, with no delay whatsoever.

However, if I put the Beep after the "Caption =" line (instead of before it)
then the beep is delayed and it occurs at the same time as the final set of
red lines appears (about half a second on my machine). And if I put a beep
both before and after the "Caption =" line I get two beeps, one the instant
I click the button and another about half a second later. So, it looks (at
the moment) as though the code is completing the For Next loop and reaching
the "StopTimer" and the "Beep" lines almost immedately (7 milliseconds) but
that VB then "hangs around for about half a second" on the "Caption = "
line. Now I'm fairly sure that a change of Caption property causes a redraw
of the Form, and I imagine that the delay is because something somewhere
"knows" that stuff is in a queue in the graphics card, and is waiting for a
signal to tell it that the queue has finally been completed and cleared, but
that's just guesswork at the moment. Mind boggling stuff, this!

> asynchronous drawing could cause all kinds of problems
> for many applications relying on GDI to draw in a certain order.


I'm inclined to agree with you there. In fact it's something I've been
considering myself. But, as the say, the proof of the pudding is in the
eating, and I'm definitely getting an "instantaneous beep" and a reported
time of just 7 milliseconds for "the whole sheebang" here.

Since the GDIFush makes no difference, and since as you say (and as I agree
with) asynchronous GDI drawing could cause all sorts of problems, then the
queue (and I'm now convinced that there actually is a queue) must be in the
hardware!

> You have _way_ too much free time on your hands!


Yep. I'll have to agree with you there ;-)

I think I'll put this stuff on the back burner now, and move to pastures new
:-)

Cheers

Mike


Ralph

2006-04-25, 6:57 pm


"Mike Williams" <mike@WhiskyAndCoke.com> wrote in message
news:%23B2qOGKaGHA.4292@TK2MSFTNGP02.phx.gbl...
> "Mike D Sutton" <EDais@mvps.org> wrote in message
> news:eh8npdGaGHA.4292@TK2MSFTNGP02.phx.gbl...
>
>
> Actually you're quite right when you say GDIFlush will make no difference,
> because it doesn't! I still get a "timed period" of just 7 milliseconds

for
> the entire loop (100 iterations of a 1000 line PolyLine). In fact I can

even
> put the GDIFlush inside the "100 iteration" loop (rather than at the end

of
> it) and it still makes no difference. Also, this morning I came to an

answer
> taking into account just one iteration), but now I can see that if the
> "timed result" is correct and actually indicates that the entire set of
> drawings has been completed then I'm getting 100 x 1000 = 100,000 lines in
> just 7 milliseconds! The instant I click the button the time appears, and
> the beep occurs (I've put a beep in now!). On average the length of each
> individual line will be something in the region of 500 pixels and if the
> time is correct then it means a single line of 500 pixels is being
> calculated and drawn in just 70 picoseconds! I know Ive got a reasonably
> fast laptop, but I'm not havin' that ;-)
>
> I amended the code a bit so as to include a Beep and so as to draw the

last
> of the 100 PolyLine drawings in red (rather than black). This is an

extract:
>
> Call StopWatch.StartTimer
> Me.ForeColor = vbBlack
> For LoopDraw = 0 To NumDraw - 1
> If LoopDraw = (NumDraw - 1) Then
> Me.ForeColor = vbRed
> End If
> Call Polyline(Me.hDC, MyPts(0), NumPts)
> Next LoopDraw
> GdiFlush
> Call StopWatch.StopTimer
> Times(0) = StopWatch.Interval
> Beep
> Caption = Format$(Times(0))
>
> Whe I run the code with the above modifications I get the "beep" and the
> first set of "1000 black lines" both at the same time, and both of them
> occur the instant I click the mouse button. However, the final set of

"1000
> red lnes" des not appea on the Form for about another half a secnd, and at
> the same time they appear the time is displayed in the Caption bar. The

time
> is 7 milliseconds, and it must be correct as far as your timer code is
> concerned because, as I've said, the "beep" occurs immediately I click the
> button, with no delay whatsoever.
>
> However, if I put the Beep after the "Caption =" line (instead of before

it)
> then the beep is delayed and it occurs at the same time as the final set

of
> red lines appears (about half a second on my machine). And if I put a beep
> both before and after the "Caption =" line I get two beeps, one the

instant
> I click the button and another about half a second later. So, it looks (at
> the moment) as though the code is completing the For Next loop and

reaching
> the "StopTimer" and the "Beep" lines almost immedately (7 milliseconds)

but
> that VB then "hangs around for about half a second" on the "Caption = "
> line. Now I'm fairly sure that a change of Caption property causes a

redraw
> of the Form, and I imagine that the delay is because something somewhere
> "knows" that stuff is in a queue in the graphics card, and is waiting for

a
> signal to tell it that the queue has finally been completed and cleared,

but
> that's just guesswork at the moment. Mind boggling stuff, this!
>
>
> I'm inclined to agree with you there. In fact it's something I've been
> considering myself. But, as the say, the proof of the pudding is in the
> eating, and I'm definitely getting an "instantaneous beep" and a reported
> time of just 7 milliseconds for "the whole sheebang" here.
>
> Since the GDIFush makes no difference, and since as you say (and as I

agree
> with) asynchronous GDI drawing could cause all sorts of problems, then the
> queue (and I'm now convinced that there actually is a queue) must be in

the
> hardware!
>
>
> Yep. I'll have to agree with you there ;-)
>
> I think I'll put this stuff on the back burner now, and move to pastures

new
> :-)
>
> Cheers
>
> Mike
>


Hey!

I found it interesting. One of the best things about this newsgroup is when
somebody else spends *their* time and saves *me* the time to go there. <g>

-ralph


Mike Williams

2006-04-25, 6:57 pm

"Ralph" <nt_consulting64@yahoo.com> wrote in message
news:7t6dnQl79oKs4tPZnZ2dnUVZ_u-dnZ2d@arkansas.net...

> Hey!
> I found it interesting. One of the best things about this
> newsgroup is when somebody else spends *their* time
> and saves *me* the time to go there. <g>


Thanks Ralph. I'm glad someone finding it interesting ;-)

Next I'm gonna create a hundred competely different sets of "1000 line
polyLine structures" and loop through them, just to see if that makes any
difference. Unless of course you'd like to do it for me and save me some
work ;-)

Mike



Ralph

2006-04-25, 6:57 pm


"Mike Williams" <mike@WhiskyAndCoke.com> wrote in message
news:OG%23GtTLaGHA.3704@TK2MSFTNGP03.phx.gbl...
> "Ralph" <nt_consulting64@yahoo.com> wrote in message
> news:7t6dnQl79oKs4tPZnZ2dnUVZ_u-dnZ2d@arkansas.net...
>
>
> Thanks Ralph. I'm glad someone finding it interesting ;-)
>
> Next I'm gonna create a hundred competely different sets of "1000 line
> polyLine structures" and loop through them, just to see if that makes any
> difference. Unless of course you'd like to do it for me and save me some
> work ;-)
>
> Mike
>


Ah,,, I think I am having trO^3uble with my GRap^hics card.

B^st U try it.

-ralph


Mike D Sutton

2006-04-26, 6:56 pm

> I will try to answer as accurately as possible to your questions.
>
> My electronic vector chart represents an area of 70 nautical miles of the
> Saint-Lawrence river (Canada). This area is divided in 3 sectors of 24
> miles or so. One polygon file, one line file and one points file for each
> sector.
>
> I start by a test to find out in which sector I am. Each polygon file
> (700K) is made of 300 or so polygons with many having holes. On the file
> they are stored with latitude and longitude x 1 million (to use long
> variables). The largest polygons have 10,000 points, the smalllest 4.
>
> Each point is compared to a reference point, at a certain scale, and X and
> Y are then obtained in pixels.
>
> The holes do not intersect. Polygons are filled with flat colors. Edges
> are drawn. Some with 2 pixels wide, most with one only. The data changes
> every minute or so, to display an area in front of a moving ship and every
> time the user changes the scale, then the chart is redrawn. Everything is
> static except the shape of a ship moving along its track.
>
> Polygons never change shape, only the size changes, along with the chosen
> scale.


Just to let you know, I'm looking into various solutions to your problem but
its taking some time.
This one for example looks particularly promising:
http://www.cs.cmu.edu/~quake/triangle.html

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@mvps.org
WWW: Http://EDais.mvps.org/


Jacquelin Hardy

2006-04-27, 7:56 am

Thank's for the link Mike

JH
"Mike D Sutton" <EDais@mvps.org> a écrit dans le message de news:
OPXo3yYaGHA.4788@TK2MSFTNGP02.phx.gbl...
> Just to let you know, I'm looking into various solutions to your problem
> but its taking some time.
> This one for example looks particularly promising:
> http://www.cs.cmu.edu/~quake/triangle.html
>
> Mike
>
>
> - Microsoft Visual Basic MVP -
> E-Mail: EDais@mvps.org
> WWW: Http://EDais.mvps.org/
>



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com