Archived

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

3DLines

This topic is 6384 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I need help- how do I make this (andre''s code) a 3D line drawer (I want it to draw 2D lines inna zbuffer. In other words. i dont want and /z''s I want a 2d line drawer that records the z location):
quote:
int Draw_Line(int x0, int y0, // starting position int x1, int y1, // ending position UCHAR color, // color index UCHAR *vb_start, int lpitch) // video buffer and memory pitch { // this function draws a line from xo,yo to x1,y1 using differential error // terms (based on Bresenahams work) int dx, // difference in x''s dy, // difference in y''s dx2, // dx,dy * 2 dy2, x_inc, // amount in pixel space to move during drawing y_inc, // amount in pixel space to move during drawing error, // the discriminant i.e. error i.e. decision variable index; // used for looping // pre-compute first pixel address in video buffer vb_start = vb_start + x0 + y0*lpitch; // compute horizontal and vertical deltas dx = x1-x0; dy = y1-y0; // test which direction the line is going in i.e. slope angle if (dx>=0) { x_inc = 1; } // end if line is moving right else { x_inc = -1; dx = -dx; // need absolute value } // end else moving left // test y component of slope if (dy>=0) { y_inc = lpitch; } // end if line is moving down else { y_inc = -lpitch; dy = -dy; // need absolute value } // end else moving up // compute (dx,dy) * 2 dx2 = dx << 1; dy2 = dy << 1; // now based on which delta is greater we can draw the line if (dx > dy) { // initialize error term error = dy2 - dx; // draw the line for (index=0; index <= dx; index++) { // set the pixel *vb_start = color; // test if error has overflowed if (error >= 0) { error-=dx2; // move to next line vb_start+=y_inc; } // end if error overflowed // adjust the error term error+=dy2; // move to the next pixel vb_start+=x_inc; } // end for } // end if /slope/ <= 1 else { // initialize error term error = dx2 - dy; // draw the line for (index=0; index <= dy; index++) { // set the pixel *vb_start = color; // test if error overflowed if (error >= 0) { error-=dy2; // move to next line vb_start+=x_inc; } // end if error overflowed // adjust the error term error+=dx2; // move to the next pixel vb_start+=y_inc; } // end for } // end else /slope/ > 1 // return success return(1); } // end Draw_Line [/QUOTE]
-Uthman Apatira almaroof@msn.com

Share this post


Link to post
Share on other sites
1 . First of all you need to separate out video memory access and line point calculation. You need to do this because your line is in 3 dimensions and video memory is at best a 2 dimensional.

1. You calculate the z component the same way you calculate the x and y.

2. Once you have your coordinate {real x, real y, real z}, you need to transform it into {screen x,screen y}.

Transformations are a whole other ballgame and there are many posts here that deal with it.

I am afraid you ill need to go back a re-think your line drawing routine. Bresenaham is a good place to start and is easily adaptable to 3d coordinates.

Share this post


Link to post
Share on other sites
umm.. no....

I dont want a 3DLine Renderer and Rasterizer, I want a 2D line that interpolates another value- like a gouraud shaded 2d line, only instead of interpolating over the color, interpolate over the z value...

Share this post


Link to post
Share on other sites
Let me see if I got this right. You want to plot 2D but keep track of the depth (z-axis) and use this value for some color interpolation, i.e. the greater the depth value the darker the color, or to be stored in a z-buffer?

If the above is not correct disregard the following:

You are still going to need the start and end positions for z.

if (dx>=0)
dz = (endz - startz) / (endx - startx)
else
dz = (endz - startz) / (endy - starty)

not only that but you will need to keep track of the {x,y} coordinate as you ''fill in'' the pixel in memory. This is necassary so that you can perform the following calculation:

if (dx >= 0)
z = dz * x
else
z = dz * y

The algorithm used in the sample code is integer based (for speed and efficiency) which means you will need some floats to keep track of the {x,y} coord.

If you are using a pentium based system the Floating Point Unit (FPU) is actually a separate CPU, so (theoretically) adding floating point maths won''t radically increase the CPU clock cycles (CPU and FPU run in parallel, and some compilers will ''interleave'' the CPU and FPU assembler for maximum throughput/efficiency).

Share this post


Link to post
Share on other sites
I am not exactly sure what you want to do, but why don''t you use the power of the 3d hardware.

In opengl, and I guess direct3d, you can do this:

Setup your endpoints of your line and then do any of the following:
1)enable or disable z checking.
1)enable or disable z writing.
1)enable or disable color writing.
1)Setup different colors for each endpoint of the line and have it interpolated.
1)Setup different blend (alpha) values for each endpoint of the line.
1)draw into the stencil buffer.
1)blend into the alpha buffer.

Share this post


Link to post
Share on other sites
it ok i got it. thanks though. what i wanted 2 do is draw a 2dline, and keep track of the zcoord 4 zbuffering, which i use in my new shadow generation algorithm.

-Uthman Apatira
almaroof@msn.com

Share this post


Link to post
Share on other sites