Fast replacement for Line command?

Blitz3D Forums/Blitz3D Programming/Fast replacement for Line command?

big10p(Posted 2007) [#1]
I'm looking for a fast replacement for Blitz's own Line command which is pretty slow, it has to be said.

There's quite a few in the code archives, but there seems to be a problem: they use WritePixelFast to plot the pixels so if the line goes off-screen, nasty things happen. Looks like blitz will blindly try to write a pixel outside of the locked image buffer, if you tell it to. :/

I don't suppose anyone knows of a fast replacement for Line that can handle lines drawn fully/partially off-screen?


b32(Posted 2007) [#2]
I think I read somewhere that you could also use Line when the buffer is Locked ?


big10p(Posted 2007) [#3]
Hmm, I doubt it. It says locked buffers should only be used by Read/WritePixelFast, in the docs.

I think I'm done for, one this one, TBH.

[edit] Actually, that does work and is quite a bit faster. I wonder how 'safe' it is, though?


b32(Posted 2007) [#4]
No idea, but it doesn't complain when drawing outside the screen. On my pc, the speed ratio is 2:3 (locked/not-locked)


_33(Posted 2007) [#5]
I'm confident that Devils Child has the answer.


big10p(Posted 2007) [#6]
b32: takes 20ms to just draw 300 lines normally on my PC, and only 2ms when locking the buffer! I wish someone (Mark/skid) could confirm whether this method is safe, or not. I might stick to using this anyway, as it's only for a small, non-serious project. Thanks for the tip!

_33: Devil's Child has a line algo in the archives - it too uses WritePixelFast. :)


_33(Posted 2007) [#7]
well, I didn't have much inspiration to write a good answer for you big10p, but now that I think of it, and it could bloody work; why not try to do a pokeint ?

You calculate the displacement by doing "(x + y * width) shl 2", and you pokeint the color + alpha value by using the handle of the imagebuffer. This should work, but I'm not 100% sure.

I'll have to try it myself sometime soon.

EDIT: Just checked, haven't been able to do a pokeint to a texture yet. If anyone is successful on doing this, I'll gladly pick up the recipe.

NOTE: If you're doing this on a texture, it shouldn't work in the case that the texture is in the GFX card memory.


_33(Posted 2007) [#8]
This:
Graphics 800,600,32,2
a = CreateImage (64, 64)
buffer = ImageBuffer (a)
For x = 0 To 63
   For y = 0 To 63
      disp = (x + y * 64) * 4
      value = Rand ($00000000, $00FFFFFF) And $FF000000
      PokeInt (buffer, disp, value)
   Next
Next
WaitKey()
...doesn't work :(

And this:
;RtlMoveMemory1%(Destination*, Source%, Length%) : "RtlMoveMemory" 
Graphics 800,600,32,2
a = CreateImage (64, 64)
For x = 0 To 63
   For y = 0 To 63
      disp = (x + y * 64) * 4
      value = Rand ($00000000, $00FFFFFF) And $FF000000
      RtlMoveMemory1(a + disp, value, 4)
   Next
Next
WaitKey()
...Still, doesn't work!

And...
;RtlMoveMemory3%(Destination*, Source*, Length%) : "RtlMoveMemory"
temp% = CreateBank(100)
Graphics 800,600,32,1
image = CreateImage (64, 64)
RtlMoveMemory3(temp, image, 100)
buffer = PeekInt (temp, 72) ; (+72) buffer graphics data pointer
Print "image is located here :" + buffer
WaitKey()
For x = 0 To 63
   For y = 0 To 63
      addr = buffer + (x + y * 64) * 4
      value = Rand ($00000000, $00FFFFFF) And $FF000000
      RtlMoveMemory1(addr, value, 4)
   Next
Next
WaitKey()
Doesn't work, but I got the image bank address.


b32(Posted 2007) [#9]
It is a good idea, however to do it is sort of complicated.
As I understood, the handle that CreateBank provides, points to a structure with a 4-byte number to indicate that it is a bank, followed by a pointer to the banks memory.
So it would be basically a pointer to another pointer.
An image has the similair structure, accessed by ImageBuffer. Before using it, you need to use LockBuffer/UnLockBuffer on it, and instead of an offset of 4-bytes, it has an offset of 72 bytes. I'm not sure if I understood it correctly, but this is basically what I could make of it.
'Tom' did this, a while ago. The thread is here: http://www.blitzbasic.com/Community/posts.php?topic=30480


_33(Posted 2007) [#10]
Definately, good! Works flawlessly on ImageBuffers!

Thoe, I'm doubtful as to if it could work on textures stored with flag 256 on.

This is something I might test tonight.

hmmmm.....
Function PointBankToTexturebuffer(b,texture)
;  Change 'Bank' to point to the TextureBuffer
   api_RtlMoveMemory (b+4,TextureBuffer(image)+IMAGEBUFFER_OFFSET,4)
   size=TextureWidth (texture) * TextureHeight (texture) * 4
   Local temp=CreateBank(4)
   PokeInt(temp,0,size)
   api_RtlMoveMemory2(b+8,temp,4)
   FreeBank temp
End Function
... It's off topic, but I would like to think this works!


TomToad(Posted 2007) [#11]
You can first clip the line to screen coordinates and then call the line function with the clipped line. That way you will know it will fall completely within the screen buffer. This site shows one method for clipping lines.
http://www.nondot.org/sabre/graphpro/line6.html

EDIT: I translated the code from that site into Blitz Basic:



Stevie G(Posted 2007) [#12]
Big10p,

Have you considered using 2d in 3d methods using single surface quads?


big10p(Posted 2007) [#13]
That PokeInt method on image buffers sounds like witchcraft, to me. :) Besides, for lines I'd need to access the back buffer which is, of course, in VRAM.

TomTom: That's interesting but I fear the additional clipping code would slow things down too much. I also noticed the lines 'wobble' when moving the clip viewport.

Stevie: This is just for a simple vector thing I'm mucking about with - it's not a major project, or anything. Writing a whole single surface system for this would be overkill, I think. :) For future reference though, has anyone done a decent 2D-in-3D vector graphics lib?


Stevie G(Posted 2007) [#14]
I'm pretty sure Indiepath did something a while back which I remember helping with. I've done some vector stuff myself.

I'll see if I can dig something out when I get home. I'm going out on a limb here but it'd be much faster than drawing clipped lines and you can make use of all the other 3d commands ( deltayaw , tform etc.. ) to get rid of all that angle cr .. [stuff] you've been discussing in other threads.

Stevie


big10p(Posted 2007) [#15]
Ah, yes - I seem to remember that Indiepath lib, now.

The reason I didn't go down the 3D route is that I actually want to do all the maths stuff myself, as a kind of learning exercise, mostly. I seem to have developed a morbid interest in trig. :) I just wanted to see if I could write a simple vector graphics game.

However, I may be interested in doing a vector game in 3D in the future as I love the graphics style.

Thanks.

P.S. Further tests show that locking the buffer for Line gives a MASSIVE speed boost. I can draw ~1000 lines before the FPS drop, and that's including all the vertex transformations I'm doing in-code, too. Should be easily fast enough for my basic needs. :)


MCP(Posted 2007) [#16]
Hi big10p, I knocked this up for you. I hope it's what your after :)



Cheers,

Roy


big10p(Posted 2007) [#17]
Thanks Roy but I was more thinking along the lines of rendering each line as a textured quad. This allows the lines to be alpha/additive blended to give them a nice glow effect.

I don't need this yet, though. I still haven't finished mucking about with vectors in pure 2D. :)


MCP(Posted 2007) [#18]
Ahhh - I see! I'll have a dabble when I get some free time. I might come up with something. :)

Cheers,

Roy


big10p(Posted 2007) [#19]
No need to go to any trouble on my behalf, but I would be interested to see what you come up with, if you do. :)


big10p(Posted 2007) [#20]
Re: Locked buffer with Line.

Interestingly, Line is the only drawing command that seems to work on locked buffers. Oval, Plot, Rect don't work - nothing is drawn. Seems like Line is some kind of special case, so maybe it is safe to use on locked buffers, then...


MCP(Posted 2007) [#21]
OK big10p,
I think I've got something more in line with what your looking for! It's definately on the right track anyway.
You can add textures too if you really want them but personally I think it looks fine the way it is :)
The idea is that you pre-cache your glowing vector geometry inside standard blitz meshes then clone as many as you like with CopyEnitity as and when you need them.
Should be fast enough!
Sorry I could'nt give you something more interesting to look at though!
Mess around with it and see what you think.



Cheers,

Roy


big10p(Posted 2007) [#22]
Thanks Roy, I'll take a look. ;)