 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
rob Guest
|
Posted: Tue Sep 07, 2004 7:59 pm Post subject: delphi graphics - tricky problem - pulling my hair out! |
|
|
I am having a hard time with some graphics code, I am hoping someone can
point me in the right direction.
I have a canvas/bitmap and it is essential to speed up the scrolling
(not the same scolling as you might do with a scrollbox) using scanline.
I have managed to get some code to work but it is too slow for my app.
The code that is using up all the run time is as follows:
LineBytes := Abs(Integer(FPlotCache.ScanLine[1]) -
Integer(FPlotCache.ScanLine[0]));
FPlotScroll.Assign(FPlotCache);
for I := -YOffset to H - 1 do
begin
Move ((FPlotCache.ScanLine[I])^,
(FPlotScroll.ScanLine[I+YOffset])^, LineBytes);
end;
Canvas.Draw(0,0,FPlotScroll);
Before and after this fragment other canvas drawing operations happen, -
after this fragment some polygons and lines are drawn. However these do
not use up significnt run time.
The move takes up pretty much all the processing time, the 'for loop' is
typically 300 and linebytes = 2000.
Seperating the scanlines from the move stops this from working - which
is very strange. I wanted to do this so I could save on calls to
scanline. However at best it just stops working and at worst the move
trashes the call stack - for no apparent reason from checking things
with the debugger.
I also tried just using one bitmap in this procedure, but for some
reason without this or the assign there is no update to the screen.
I have been wondering if another thread (none of mine do) is changing
things. I am running effectively with 2 processors.
That might explain why seperating the scanline calls from the move
results in program failure.
Thanks for reading this - hoping someone can help :-)
Rob
|
|
| Back to top |
|
 |
Nils Haeck Guest
|
Posted: Tue Sep 07, 2004 8:40 pm Post subject: Re: delphi graphics - tricky problem - pulling my hair out! |
|
|
I see there's an "abs" in the LineBytes call, very dangerous! The reason is
that scanlines in some bitmaps may be reversed (so the bitmap's lowest
visual scanline is first in memory).
What you can do is detect if
LineBytes := Integer(FPlotCache.ScanLine[1]) -
Integer(FPlotCache.ScanLine[0]);
if LineBytes < 0 then
.... scanline[0] is at the end of the memory
else
... scanline[0] is at the start of the memory (as you would intuitively
expect)
Concerning updates not appearing, try
Canvas.Lock;
try
.. do your scanline stuff here
finally
Canvas.Unlock;
end;
And make sure to invalidate your image (this happens automatically in the
Draw call, but not neccesarily if you manipulate using scanlines), and
perhaps call "Application.ProcessMessages"
Kind regards,
Nils
www.simdesign.nl
"rob"
| Quote: | I am having a hard time with some graphics code, I am hoping someone can
point me in the right direction.
I have a canvas/bitmap and it is essential to speed up the scrolling
(not the same scolling as you might do with a scrollbox) using scanline.
I have managed to get some code to work but it is too slow for my app.
The code that is using up all the run time is as follows:
LineBytes := Abs(Integer(FPlotCache.ScanLine[1]) -
Integer(FPlotCache.ScanLine[0]));
FPlotScroll.Assign(FPlotCache);
for I := -YOffset to H - 1 do
begin
Move ((FPlotCache.ScanLine[I])^,
(FPlotScroll.ScanLine[I+YOffset])^, LineBytes);
end;
Canvas.Draw(0,0,FPlotScroll);
Before and after this fragment other canvas drawing operations happen, -
after this fragment some polygons and lines are drawn. However these do
not use up significnt run time.
The move takes up pretty much all the processing time, the 'for loop' is
typically 300 and linebytes = 2000.
Seperating the scanlines from the move stops this from working - which
is very strange. I wanted to do this so I could save on calls to
scanline. However at best it just stops working and at worst the move
trashes the call stack - for no apparent reason from checking things
with the debugger.
I also tried just using one bitmap in this procedure, but for some
reason without this or the assign there is no update to the screen.
I have been wondering if another thread (none of mine do) is changing
things. I am running effectively with 2 processors.
That might explain why seperating the scanline calls from the move
results in program failure.
Thanks for reading this - hoping someone can help :-)
Rob
|
|
|
| Back to top |
|
 |
Wayne Herbert Guest
|
Posted: Tue Sep 07, 2004 9:32 pm Post subject: Re: delphi graphics - tricky problem - pulling my hair out! |
|
|
rob wrote:
| Quote: | I am having a hard time with some graphics code, I am hoping someone can
point me in the right direction.
I have a canvas/bitmap and it is essential to speed up the scrolling
(not the same scolling as you might do with a scrollbox) using scanline.
I have managed to get some code to work but it is too slow for my app.
The code that is using up all the run time is as follows:
LineBytes := Abs(Integer(FPlotCache.ScanLine[1]) -
Integer(FPlotCache.ScanLine[0]));
FPlotScroll.Assign(FPlotCache);
for I := -YOffset to H - 1 do
begin
Move ((FPlotCache.ScanLine[I])^,
(FPlotScroll.ScanLine[I+YOffset])^, LineBytes);
end;
Canvas.Draw(0,0,FPlotScroll);
Before and after this fragment other canvas drawing operations happen, -
after this fragment some polygons and lines are drawn. However these do
not use up significnt run time.
The move takes up pretty much all the processing time, the 'for loop' is
typically 300 and linebytes = 2000.
Seperating the scanlines from the move stops this from working - which
is very strange. I wanted to do this so I could save on calls to
scanline. However at best it just stops working and at worst the move
trashes the call stack - for no apparent reason from checking things
with the debugger.
I also tried just using one bitmap in this procedure, but for some
reason without this or the assign there is no update to the screen.
I have been wondering if another thread (none of mine do) is changing
things. I am running effectively with 2 processors.
That might explain why seperating the scanline calls from the move
results in program failure.
Thanks for reading this - hoping someone can help :-)
Rob
|
Is the point of this to scroll an image on screen? Why not just use a
PaintBox and/or a CopyRect? If you want to draw rubber lines or moving
bitmaps, the paintbox is great. I don't understand what you are trying
to acocmplish.
|
|
| Back to top |
|
 |
K. Sallee Guest
|
Posted: Wed Sep 08, 2004 5:27 am Post subject: Re: delphi graphics - tricky problem - pulling my hair out! |
|
|
| Quote: | Why not just use a PaintBox and/or a CopyRect?
|
PaintBox tends to flicker.
(some solutions : http://www.bcbdev.com/faqs/faq34.htm#tpaintbox)
However, CopyRect is a good suggestion.
Kevin
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
|
|
| Back to top |
|
 |
Wayne Herbert Guest
|
Posted: Wed Sep 08, 2004 3:02 pm Post subject: Re: delphi graphics - tricky problem - pulling my hair out! |
|
|
K. Sallee wrote:
Putting the PaintBox onto a component that can be double buffered (such
as a TPanel) and setting the DoubleBuffered property to true eliminates
flicker. Unless extreme graphics speed is needed, the slowdown due to
the offscreen bitmap is marginal.
|
|
| Back to top |
|
 |
rob Guest
|
Posted: Wed Sep 08, 2004 8:38 pm Post subject: Re: delphi graphics - tricky problem - pulling my hair out! |
|
|
Yup, Thanks for that,
However having tried all that - and more, I am still getting strange
unreliable behaviour.
No doubt I am missing something, but I will have to pass on
investigating it further. The original reason for using scanline was a
convenience that gave added flexibility. I think it will be too risky to
code it with scanline. Instead I have re-arranged the canvases etc.
and now for this part I can forget scanline completely and just
reposition the bitmap using canvas.draw. This works reliably and appears
to work very fast: 200 times improvement in speed which is more than
good enough for me.
Thanks again :-)
Rob
Nils Haeck wrote:
| Quote: | I see there's an "abs" in the LineBytes call, very dangerous! The reason is
that scanlines in some bitmaps may be reversed (so the bitmap's lowest
visual scanline is first in memory).
What you can do is detect if
LineBytes := Integer(FPlotCache.ScanLine[1]) -
Integer(FPlotCache.ScanLine[0]);
if LineBytes < 0 then
... scanline[0] is at the end of the memory
else
.. scanline[0] is at the start of the memory (as you would intuitively
expect)
Concerning updates not appearing, try
Canvas.Lock;
try
.. do your scanline stuff here
finally
Canvas.Unlock;
end;
And make sure to invalidate your image (this happens automatically in the
Draw call, but not neccesarily if you manipulate using scanlines), and
perhaps call "Application.ProcessMessages"
Kind regards,
Nils
www.simdesign.nl
"rob"
news:413e1325 (AT) newsgroups (DOT) borland.com...
|
|
|
| Back to top |
|
 |
rob Guest
|
Posted: Wed Sep 08, 2004 8:46 pm Post subject: Re: delphi graphics - tricky problem - pulling my hair out! |
|
|
Hi Guys thanks for the suggestions. :-)
I rearranged my canvases etc and now i cam move stuff around by using
canvas.draw(n,m,bitmap) this works reliably and is plenty fast enough
and keeps things simple. scanline has proved too unreliable in my hands
and this application needs to work in all sorts of places.
Rob :-)
Wayne Herbert wrote:
| Quote: | K. Sallee wrote:
Why not just use a PaintBox and/or a CopyRect?
PaintBox tends to flicker.
(some solutions : http://www.bcbdev.com/faqs/faq34.htm#tpaintbox)
However, CopyRect is a good suggestion.
Kevin
Putting the PaintBox onto a component that can be double buffered (such
as a TPanel) and setting the DoubleBuffered property to true eliminates
flicker. Unless extreme graphics speed is needed, the slowdown due to
the offscreen bitmap is marginal.
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|