Archived

This topic is now archived and is closed to further replies.

webmunkey

3D Accelerated... Lines?

Recommended Posts

Okay, I was just wondering how I can use Direct3d 8 to draw 3d lines. I am aware that DrawPrimitive does have a draw line function that uses a vertex buffer to draw a line using like LINELIST. This is all just great, but I the lines I''m drawing are going to be have constantly different vertices. That would mean locking and unlocking the vertex buffer each time I wanted to draw a line, right? Well, that''s way too slow, I might as well just lock the surface and plot pixels on my own. Can anyone think of a fast way around the problem? Basically I want to be able to draw lots of pixel thick lines with widly varying vertices as quick as computerly possible. Any ideas would be greatly welcomed! Also how fast is the ''hack'' of using the clear function and passing it a rectangle? Cheers, -Jesse

Share this post


Link to post
Share on other sites
clear is pretty darn fast...

Also, I''m usually telling everyone not to lock, mainly because many people lock instead of doing simple transforms. However, there are some cases where you just have to. If that''s the case, then it''s really not *that* slow, and it''s probably much much faster than locking and drawing individual pixels. If you set everything up correctly, locking the buffer should still be very acceptable - don''t discount it. But remember, if you''re just doing simple translations, rotations, and scaling, you are better off with the matrices...

The one issue is that DX8 doesn''t really have a line width setting. If you want wider lines, set up the basic lines and then render more than once, "jittering" thine lines with matrices. There are a couple of ways of doing this, but the jittering way allows you to play with transparency for antialiasing effects.

Share this post


Link to post
Share on other sites
It seems that the all mighty "clear hack" do draw pixel thick lines without locking is incredibly slow when it comes to calling it 3200 times or so , god I love voxel engines. I was thinking about having a vertex buffer that had a vertex for every pixel on the screen in a vertical fashion so that the engine could call the two verticies it wants to draw the line between, or is that just an incredibly unrealistic idea memory wise? We're talking about resolutions of 640x480 to 800x600 here, so... Does anyone else have any other ideas? I really don't want to lock buffers if it can be avoided, and remeber, speed is key here.
Thanks,
-Jesse

[Edit: I'm an idiot, don't pay attention]

Edited by - webmunkey on November 5, 2001 6:28:36 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Code up some different line draw engines and see. Each should only take a little while, like a couple of hours. Streaming into a VB is probably the fastest for the newer video cards.

Share this post


Link to post
Share on other sites
Locking is probably much faster/easier/saner than keeping a vertex for every pixel! Remember, some cards have a vertex buffer limit of 65K - much less than every pixel.

If you can''t accomplish what you need with the transforms, then you probably have to lock. The speed it runs is the speed it runs.

One question - what are you doing?? Sometime people say they are just translating points. That''s a matrix problem. Others are doing things that may be solved with shaders, some have to lock... Whatcha doin?

Share this post


Link to post
Share on other sites
I am currently building a super-fast voxel engine, I just think that it could be faster if I could plot 3d accelerated lines because, while locking surface with directdraw and plotting pixels using asm is fast, its ugly and unflexible. D3D lines open up all sorts of texture blending effects and lighting transformations and all that fun stuff. But I still can't figure out how to draw fast d3d lines. I've tried clear rects, d3d linestrips and good old fashion pixel plotting and so far, pixel plotting is ripping the other two methods to shreds speed wise, much to my dismay.
Anarchi: Drawing lines isn't hard, but I'll send you a small tutorial nonetheless. It's poorly documented in the DX8 docs, but it is there, in the DrawPrimitive function. My email sucks, so it could take a day or two for it to reach you. I'm going to assume that you want lines in a 2d environment.

Anyone else who has any suggestions for fast line drawing, please post.

Cheers,
-Jesse

Edited by - webmunkey on November 6, 2001 8:13:25 PM

Share this post


Link to post
Share on other sites
You should try using DrawPrimitiveUP so that you don''t have to lock your VB''s. Just change the vertices. I have gotten pretty good speed with this also.

*** Triality ***

Share this post


Link to post
Share on other sites
If the UP function should be avoided, then what should I use? Keep in mind that I'm always drawing vertical lines. Can I offset a line's vertices with a matrix, so that I could grab a, say, 50-pixel long line, move it over 20, and down 50 without locking/unlocking? Maybe this could be acheived through manipulation of the view matrices? I'm not quite sure, this is about the extent of my Direct3d knowledge, I've always just used two matrices for my custom 3d-engines, but d3d has 3. Anyway, any other ideas would welcomed as well. Thanks to everyone who has contributed to the post so far,
Cheers,
-Jesse

Edited by - webmunkey on November 7, 2001 4:52:08 PM

Share this post


Link to post
Share on other sites
Use UP. The advantage to vertex buffers is that you can store a lot of static geometry on the card and then view it from different positions by sending the card a new matrix, thereby avoiding having to send all new point positions. If you had a large amount of lines which couls all be repositioned with a single matrix, this would be a win for you, but if you need to reposition each line separately it''s not.

Or just benchmark various schemes.

Share this post


Link to post
Share on other sites
Jeff K: But doesn''t UP automatically lock and unlock the vertex buffer for you when it is called? If that''s the case, I''ve all ready used DrawPrimitive locking and unlocking the vertex buffer, and it is too slow. By the way, I performed a benchmark test using clear, drawprim - linestrip and asm pixel plotting. The pixel plotting won by about 20 fps, drawprim came in second by about 5.
Cheers,
-Jesse

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by webmunkey
If the UP function should be avoided, then what should I use? Keep in mind that I''m always drawing vertical lines. Can I offset a line''s vertices with a matrix, so that I could grab a, say, 50-pixel long line, move it over 20, and down 50 without locking/unlocking? Maybe this could be acheived through manipulation of the view matrices?

This sounds like it would work (I have no idea if it will be faster though). Keep a vertex-buffer with vertices for a single screen-column (won''t be very large), and then offset it in the X direction with the model-matrix. This way you will never have to lock the VB, only change the matrix.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Anonymous Poster: Yeah, I was kind of thinking about something like that myself. However, there is one big problem that comes to mind. The "generic" vertex buffer is going to be big because even though it is one column composed of 480 or so pixels, if all the base vertices started from 480, then there would only be 480 different kinds of lines, however, the base vertices move as well, causing there to be a lot more lines. This means that translation on the y-axis would be a nescessity. So the question is, how would I best setup a matrix that can be multiplied against the x and y values in order to translate them?
Another possible solution that came to mind was using LINESTRIP, and tracking the vertices of the voxel columns with arrays, then at the last second performing only one lock per column and pasting in the array defined vertices. The LINESTRIP function would then share the vertices, cutting down vertex processing time, and furthermore, the vertex buffer would only be locked 640 times a frame (i''ll have to perform a benchmark to see what kind of performance hit that brings), instead of being locked 307200 or so times per frame. Suggestions?
Thanks,
-Jesse

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Anonymous Poster
Anonymous Poster: Yeah, I was kind of thinking about something like that myself. However, there is one big problem that comes to mind. The "generic" vertex buffer is going to be big because even though it is one column composed of 480 or so pixels, if all the base vertices started from 480, then there would only be 480 different kinds of lines, however, the base vertices move as well, causing there to be a lot more lines

Why does it matter that the baselines move? It shouldn''t if you are using indexed primitives.

e.g: you need to draw a line between (5,30) and (5,50), use the model-matrix to offset rendering 5 units along the x-axis, and then draw a line between the coordinates with indexes 30 and 50 (which would be predefined in the vertex buffer as (0,30) and (0,50) respectively).

Perhaps I have totally misunderstood what you''re trying to do.

Come to think of it you would have to lock and modify an index buffer, since you don''t want to call DrawPrimitive for each line. Perhaps there is no/little gain to this method (you could of course try it, it shouldn''t be pretty easy).

Share this post


Link to post
Share on other sites
Is it required that you use DX8, are you doing going to be doing 3D? Why not go back to DX7 and use direct draw? Make your lines as buffers in video memory and blt them from vid mem to the back buffer flip and repeat.

A possibilty, but I don''t know if your required to use DX8

Share this post


Link to post
Share on other sites
Nope it isn''t required that I use dx8, it isn''t even required that I use dx. I already have a voxel engine that runs using direct draw and pixel plotting. However, above resolutions of 640 x 480, speed becomes a problem. This partly due to the fact that the interpolation equations take awhile, and the pixel / line drawing alogrithms aren''t the fastest in the world. I''d like to push my engine into the 800 x 600 range, but in order to do that, I''ll need faster interpolation equations and line drawing. D3D8 has nice fast color interpolation and opens up the possiblity of 3d accelerated line drawing. This technique was first used in Land Warrior, and it is lightning fast. I''m trying to recreate that speed... so this is where I am now. Anyhow,
Anonymous Poster: I see what you''re saying now, that''s a pretty good idea. I was thinking of something along that line, but not exactly like how you put it. I could call DrawPrimtive for each line very easily, getting rid of the buffer lock / unlock problem, however, I wonder how expensive the DrawPrimitive call is... I''ll create some more benchmarks and let you guys know.
Thanks,
-Jesse

Share this post


Link to post
Share on other sites