Qbasicnews.com
February 26, 2020, 01:21:44 AM
 Pages: 1 [2] 3 4
 Author Topic: Triangle routine gone haywire  (Read 10519 times)
relsoft
*/-\*

Posts: 3927

 « Reply #15 on: May 28, 2003, 02:09:16 AM »

well if you are using SETVIDEO Seg then you might wanna use paint.

Just do this to fine the center of a tri(works for any convex poly too)

Paint((x1+x2+x3)/3,(y1+y2+y3)/3),clr

Or there is a very good tute someone from finland(3dIca) which is very fast only using Horizontal lines which (I believe) CGI JOe/Generic utilized in his demo which I in turn used and modified for my 3d rotators.

The source could be found  somewhere in this forum.  I think projects.
 Logged

y smiley is 24 bit.

Genso's Junkyard:
http://rel.betterwebber.com/
Antoni Gual
Na_th_an

Posts: 1434

 « Reply #16 on: May 28, 2003, 10:07:43 AM »

I ripped the routine from my 3d mesh viewer. Two comments.

1.- With a single triangle most of the time is spent in copying buffer to screen. I removed buffer and i have an incredible 500 fps in my P4. If you are drawing a complete mesh the buffer operations are not so important.

2.-The original routine had sub-pixel accuracy and a 640x480 screen. In screen 13 the lack of accuracy is evident. I imagine someone could fine tune it...

Code:

DECLARE SUB TRIANGLE3 (X1%, Y1%, X2%, Y2%, X3%, Y3%, C%)
DEFINT A-Z
DIM SHARED LUTSEGY(199) AS LONG

CONST pi180 = 3.141592654# / 180

NN& = &HA000
FOR N% = 0 TO 199
LUTSEGY(N%) = NN&
NN& = NN& + 20
NEXT

SCREEN 13

DIM SINt%(120), COSt%(120)
FOR i% = 0 TO 120
SINt(i%) = 30 * SIN(3 * i% * pi180)+149
COSt(i%) = 30 * COS(3 * i% * pi180)+189
NEXT

ang1 = 0
ang2 = 40
ang3 = 80
fr% = 0
t# = TIMER
DO

X1 = COSt(ang1)
Y1 = SINt(ang1)
X2 = COSt(ang2)
Y2 = SINt(ang2)
X3 = COSt(ang3)
Y3 = SINt(ang3)
PAINT (189, 149), 0
TRIANGLE3 X1, Y1, X2, Y2, X3, Y3, 4
IF ang1 < 120 THEN ang1 = ang1 + 1 ELSE ang1 = 1
IF ang2 < 120 THEN ang2 = ang2 + 1 ELSE ang2 = 1
IF ang3 < 120 THEN ang3 = ang3 + 1 ELSE ang3 = 1
fr% = fr% + 1
LOOP UNTIL LEN(INKEY\$)
PRINT fr% / (TIMER - t#)
a\$ = INPUT\$(1)

REM \$STATIC
SUB TRIANGLE3 (X1%, Y1%, X2%, Y2%, X3%, Y3%, C%)
'
'reorder coords so y1<y2<y3
'
IF Y2 > Y3 THEN SWAP X2, X3: SWAP Y2, Y3
IF Y1 > Y2 THEN SWAP X1, X2: SWAP Y1, Y2
IF Y2 > Y3 THEN SWAP X2, X3: SWAP Y2, Y3
'
'find which side is x2,y2 from(x3,y3)-(x1,y1) s=1 right, -1 left
'
IF Y1 <> Y3 THEN
IF X2 > X1 AND X2 > X3 THEN
s = 1
ELSEIF X2 < X1 AND X2 < X3 THEN
s = -1
ELSE
s = SGN((Y3 - Y1) * (X2 - X1) - (Y2 - Y1) * (X3 - X1))
END IF
END IF
'
'calculate Bresenham coefs of sides to calc start and end point of scanlines
'
IF s < 0 THEN
tl = X2 - X1: tr = X3 - X1
dyl = Y2 - Y1: dyr = Y3 - Y1
ELSE
tl = X3 - X1: tr = X2 - X1
dyl = Y3 - Y1: dyr = Y2 - Y1
END IF
dxl = ABS(tl): sxl = SGN(tl): el = 0
dxr = ABS(tr): sxr = SGN(tr): er = 0
'
'at the top of triangle scanline both starts and ends at x1

xx = X1
xxx = X1
'
'for each scanline
'
FOR scanline = Y1 TO Y3

'
'if arrived to y2 we must change Bresenham coeficients of one side
'
IF scanline = Y2 THEN
IF s < 0 THEN
'
'if dyl=0, flat bottom, end
'
dyl = Y3 - Y2: IF dyl = 0 THEN EXIT SUB
tl = X3 - X2
dxl = ABS(tl): sxl = SGN(tl): xx = X2
ELSE
'
'if dyr=0, flat bottom, end
'
dyr = Y3 - Y2: IF dyr = 0 THEN EXIT SUB
tr = X3 - X2
dxr = ABS(tr): sxr = SGN(tr): xxx = X2
END IF
END IF

'
'draw scanline!
'
ll = scanline
DEF SEG = LUTSEGY(ll)
FOR x = xx TO xxx
POKE x, C%
NEXT
'
'Use Bresenham to calculate start of next scanline
'
WHILE el < 0: el = el + dyl: xx = xx + sxl: WEND
el = el - dxl
'
'Use Bresenham to calculate end of next scanline
'
WHILE er < 0: er = er + dyr: xxx = xxx + sxr: WEND
er = er - dxr
NEXT scanline
END SUB

 Logged

Antoni
Ninkazu
Been there, done that

Posts: 1169

 « Reply #17 on: May 28, 2003, 05:12:56 PM »

Whoa..... that's cool. Do you think you could find the time to explain that, because I'm not quite sure how that works. Also, if you don't mind, could you go over texture mapping? (I'm not sure if it's affine or perspective...)

I got 641fps on my P3
 Logged

am an asshole. Get used to it.
relsoft
*/-\*

Posts: 3927

 « Reply #18 on: May 29, 2003, 12:38:02 AM »

My 3d rotator has Affine texture mapper again Modified from CGI Joes and 3d Ica's codes.  If I  could find the time tomorrow I'll post it.
 Logged

y smiley is 24 bit.

Genso's Junkyard:
http://rel.betterwebber.com/
Ninkazu
Been there, done that

Posts: 1169

 « Reply #19 on: May 29, 2003, 01:02:23 AM »

Please do, along with an explanation of what the code is actually doing....
 Logged

am an asshole. Get used to it.
relsoft
*/-\*

Posts: 3927

 « Reply #20 on: May 29, 2003, 01:07:10 AM »

Okay, It uses Fixpoint though. ;*(  10 Bits.

But yeah I'll try to comment it.

In essence it's like Gouraud shading but the interpolation is done with U and V instead of Colors.
 Logged

y smiley is 24 bit.

Genso's Junkyard:
http://rel.betterwebber.com/
Ninkazu
Been there, done that

Posts: 1169

 « Reply #21 on: May 29, 2003, 08:23:36 AM »

Why is fixed point bad? I thought it was fast...
 Logged

am an asshole. Get used to it.
Antoni Gual
Na_th_an

Posts: 1434

 « Reply #22 on: May 29, 2003, 10:06:27 AM »

Fixed point is much faster than floating point, this is why I  use it in the IDCT routine of my JPEG viewer.But it needs products and divides to rescale values. If you can use a routine that only adds, substracts and looks up in tables it will be faster than another one using mult and divide, even if it's all integer.

In the case of the slope of a straight line, you can put it in the form of a fraction (y2-y1)/(x2-x1), so you can get all intermediate points with all adds and substracts.

Code:

DEFINT a-z
SCREEN 13
x1 = 0: y1 = 0
x2 = 50: y2 = 100
dy = y2 - y1
dx = x2 - x1
e = 0
x = x1
FOR y = y1 TO y2
PSET (x, y), 15
e = e + dx
WHILE e > 0: e = e - dy: x = x + 1: WEND
NEXT
 Logged

Antoni
Jark
Ancient Guru

Posts: 566

 « Reply #23 on: May 29, 2003, 10:38:43 PM »

My question will sound really stupid... but what the hell are you doing with triangles in a QB pog ? (Somehow provocative, but who cares).

The only use I know for triangles in programming is related with raytracing : you build a fishnet, then a triangle every three points.

 Logged

hink Global, Make Symp' All ! ®
Ninkazu
Been there, done that

Posts: 1169

 « Reply #24 on: May 29, 2003, 11:01:57 PM »

Triangles are the basis of all 3D programs... Why not do 3D in QB?
 Logged

am an asshole. Get used to it.
relsoft
*/-\*

Posts: 3927

 « Reply #25 on: May 30, 2003, 12:07:38 AM »

Here Ninkazu.

I commented it as much as I can along with a lil tut on vectors and Interpolation:

[code]

'//// Little tut on vectors by RelSoft
'//// May, 29, 2003, 9PM
'//// Evanescence playing in the BG.... "Must buy" album.
'//// PolyFillers by "The Coder Formerly Known as CGI JOE)"/Generic
'//// Polyfillers modified slightly.
'//// I won't include a 3d rotator here or I won't be able to add to Dw3 and
'//// Jofer's would cut my Ballz. ;*)

DECLARE SUB Tritexture (textseg%, xx1%, yy1%, uu1%, vv1%, xx2%, yy2%, uu2%, vv2%, xx3%, yy3%, uu3%, vv3%)
DECLARE SUB TriGouraud (xx1%, yy1%, Cc1%, xx2%, yy2%, Cc2%, xx3%, yy3%, Cc3%)
DECLARE SUB HLine (x1%, x2%, Y%, Col1&, Col2&)
DECLARE SUB HTLine (xx1%, xx2%, yy%, uu1&, uu2&, vv1&, vv2&)
DEFINT A-Z

RANDOMIZE TIMER
CLS
SCREEN 13

'Grey Scale the Palette
FOR I = 0 TO 255
OUT &H3C8, I
OUT &H3C9, I \ 4
OUT &H3C9, I \ 6
OUT &H3C9, I \ 8
NEXT I

'//// See Hline and TriGouraud SUBS.....

DO
x1 = INT(RND * 320)
x2 = INT(RND * 320)
x3 = INT(RND * 320)
y1 = INT(RND * 200)
y2 = INT(RND * 200)
y3 = INT(RND * 200)
c1 = INT(RND * 256)
c2 = INT(RND * 256)
c3 = INT(RND * 256)
TriGouraud x1, y1, c1, x2, y2, c2, x3, y3, c3

LOOP UNTIL INKEY\$ <> ""

'/////Texture!!!!
'Notes:
'3d to 2d formula
'X2d=X/z
'Y2d=Y/z

'X2d=X/Distace
'Y2d=Y/Distace

'Assuming X=1 and Y=1....
'Calculating U anv V for each Point......
'u_texture = u_2D / z_2D,
'v_texture = v_2D / z_2D,
'or
'u_texture = (u/z) / (1/z)
'v_texture = (v/z) / (1/z)

'How to calculate the U and V coords of each Poly or Face
'u = vertex u coord
'v = vertex v coord
'VertexNormal is the normal to a point. Yeah I know we can't get a
'perpendicular/Orthogonal vector(normal) to a point but
'the way we calc it is to get all the normals of planes adjacent
'to the vertex, add em and divide the product by how amny faces/planes
'you found.

'Be sure the Vertexnormal is normalized. Books call that "Unit Vectors"
'Normals are calculated using the Cross Product which gives you a Vector.
'*Not to confuse with the Dot product which gives you the Cos(Theta)
'A SCALAR.

'To get a vector between 2 3d points(X,Y,Z)...
'Point 1=(ax,ay,az)
'Point 2=(bx,by,bz)
'AB = (Bx-Ax,By-Ay,Bz-Az)= (X,Y,Z).
'Magnitude:
'|AB| = sqrt( X^2 + Y^2 + Z^2 )
'To get the "Normalized" or Unit Vector which could have
'values from -1 to 1.:

'UnitVector=AB/|AB|

'In 2d matrix, you could use:
'Cramer's Rule
'A B
'C D

'In 3d:

'aX aY aZ
'bx bY bz
'= ( Ay*Bz-By*Az , Az*Bx-Bz*Ax , Ax*By-Bx*Ay )

'IMPORTANT~!!!!!!
'Use the NON-ROTATED Vertex Normal.

'Assuming your Texture size is  128 * 128

'For I=0 to NumberofPolys
'Poly(I).u1 = Vertexnormal(Poly(I).x1) *128 + 127   'Textsize
'Poly(I).v1 = Vertexnormal(Poly(I).y1) *128 + 127
'Poly(I).u2 = Vertexnormal(Poly(I).x2) *128 + 127
'Poly(I).v2 = Vertexnormal(Poly(I).y2) *128 + 127
'Poly(I).u3 = Vertexnormal(Poly(I).x3) *128 + 127
'Poly(I).v3 = Vertexnormal(Poly(I).y3) *128 + 127
'Next

'//////===Start Code....

'Texture....
DIM SHARED Texture%(32 * 32)                        'Nice textures

'Set up our texture
FOR Y = 0 TO 63
FOR X = 0 TO 63
PSET (X, Y), ((Y XOR X)) + 50
NEXT X
NEXT Y

'Poke it to the darnd Bitmap
DEF SEG = VARSEG(Texture%(0))
offs& = 0
FOR Y = 0 TO 31
FOR X = 0 TO 31
C = POINT(X, Y)
POKE offs&, C
offs& = offs& + 1
NEXT X
NEXT Y

DEF SEG

'Draw some textured tri's
DO

x1 = INT(RND * 320)        'Random Points
x2 = INT(RND * 320)
x3 = INT(RND * 320)
y1 = INT(RND * 200)
y2 = INT(RND * 200)
y3 = INT(RND * 200)
Z1 = 256 - INT(RND * 256)
Z2 = 256 - INT(RND * 256)
Z3 = 256 - INT(RND * 256)
GOSUB CalcFaceNormal            'Vertex 1
u1 = (VertexNx! * 31) + 31
v1 = (VertexNy! * 31) + 31
GOSUB CalcFaceNormal            'vertex 2
u2 = (VertexNx! * 31) + 31
v2 = (VertexNy! * 31) + 31
GOSUB CalcFaceNormal            'vertex 3
u3 = (VertexNx! * 31) + 31
v3 = (VertexNy! * 31) + 31

Tritexture VARSEG(Texture%(0)), x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3

LOOP UNTIL INKEY\$ <> ""

CLS
SCREEN 0
WIDTH 80
END

CalcFaceNormal:
'/=========
'VertexNormal
'Algo: since we cannot find a normal to a point(doh?!!!) we find adjacent
'planes(faces) of the polyhedra that a vertex is located then adding
'all the facenormals of all the faces that a particular vertex is
'located.
'Damn!!!! This is HARD using only ONE FACE!!!! Insanely impossible!!!

Txnormal! = 0
Tynormal! = 0
Tznormal! = 0
FaceFound = 1                   'Just one face. ;*)

'Emulate 3 Faces
FOR I = 1 TO 3
xx1 = INT(RND * 320)        'Random Points
xx2 = INT(RND * 320)
xx3 = INT(RND * 320)
yy1 = INT(RND * 200)
yy2 = INT(RND * 200)
yy3 = INT(RND * 200)
zz1 = INT(RND * 256)
zz2 = INT(RND * 256)
zz3 = INT(RND * 256)

'Derive vector
'AB = (Bx-Ax,By-Ay,Bz-Az)= (X,Y,Z).
ax! = xx2 - xx1
bx! = xx3 - xx2
ay! = yy2 - yy1
by! = yy3 - yy2
az! = zz2 - zz1
bz! = zz3 - zz2

'Cross product
'(Ay*Bz-By*Az , Az*Bx-Bz*Ax , Ax*By-Bx*Ay)

xnormal! = ay! * bz! - az! * by!
ynormal! = az! * bx! - ax! * bz!
znormal! = ax! * by! - ay! * bx!

'Normalize
'Length
'|AB| = sqrt( X^2 + Y^2 + Z^2 )

Mag! = SQR(xnormal! ^ 2 + ynormal! ^ 2 + znormal! ^ 2)
IF Mag! <> 0 THEN
xnormal! = xnormal! / Mag!
ynormal! = ynormal! / Mag!
znormal! = znormal! / Mag!
END IF

IF znormal! < -1 THEN
znormal! = -1
ELSEIF znormal! > 1 THEN
znormal! = 1
END IF

IF xnormal! < -1 THEN
xnormal! = -1
ELSEIF xnormal! > 1 THEN
xnormal! = 1
END IF

IF ynormal! < -1 THEN
yxnormal! = -1
ELSEIF ynormal! > 1 THEN
ynormal! = 1
END IF

Txnormal! = Txnormal! + xnormal!
Tynormal! = Tynormal! + ynormal!
Tznormal! = Tznormal! + znormal!
NEXT I

Txnormal! = Txnormal! / FaceFound       'Numfaces found
Tynormal! = Tynormal! / FaceFound
Tznormal! = Tznormal! / FaceFound
VertexNx! = Txnormal!
VertexNy! = Tynormal!
VertexNz! = Tznormal!

RETURN

SUB HLine (x1%, x2%, Y%, Col1&, Col2&)
'Rels Note: I emulated the BYVAL parameter passing since I was getting errors
'in the Gouraud and texture stuff

xx1% = x1%
xx2% = x2%
yy% = Y%
Clr1& = Col1&
Clr2& = Col2&

'Swap values not in order
IF xx1% > xx2% THEN SWAP xx1%, xx2%: SWAP Clr1&, Clr2&

'Rel's notes:
'INTERPOLATION
'f(X) = A + X*((B-A)/steps),
'where we slide from A to B in steps and
'f'(X) (the derivative of f(X)), the growing speed of
'f(X) that is, is (B-A)/steps.

'so....
'A=xx1 or clr1  'depends on what you wan't to interpolate
'B=xx2 or clr2  'depends on what you wan't to interpolate
'Xdiff=Steps
'Dc&=(B-A)/Steps or F'(x)
'We won't use X*Dc& as we are adding inside the loop.
'Fun fact!!! Multiplication is just a series of addition. ;*)

'since this is Gouraud, we don't interpolate between x1 and x2 but c1 and c2

xdiff% = 1 + xx2% - xx1%        'Get Delta

dc& = (Clr2& - Clr1&) \ xdiff%      'interpolate    Dc=Steps.
col& = Clr1&

FOR l% = xx1% TO xx2%           'Draw interpolated HorizLine
PSET (l%, yy%), col& \ 65536
col& = col& + dc&
NEXT l%

END SUB

SUB HTLine (xx1%, xx2%, yy%, uu1&, uu2&, vv1&, vv2&)
'Generic's
'Rels Note: I emulated the BYVAL parameter passing since I was getting errors
'in the Gouraud and texture stuff

x1% = xx1%
x2% = xx2%
Y% = yy%
u1& = uu1&
v1& = vv1&
u2& = uu2&
v2& = vv2&

IF x1% > x2% THEN SWAP x1%, x2%: SWAP u1&, u2&: SWAP v1&, v2&
xdiff% = 1 + x2% - x1%

du& = (u2& - u1&) \ xdiff%
dv& = (v2& - v1&) \ xdiff%

u& = u1&
v& = v1&

FOR l% = x1% TO x2%
u% = (u& \ 65536) AND 31
v% = (v& \ 65536) AND 31
col% = PEEK(u% + v% * 32)
PSET (l%, Y%), col%
u& = u& + du&
v& = v& + dv&
NEXT l%

END SUB

SUB TriGouraud (xx1%, yy1%, Cc1%, xx2%, yy2%, Cc2%, xx3%, yy3%, Cc3%)
'Generic's routine..
'Rels Note: I emulated the BYVAL parameter passing since I was getting errors
'in the Gouraud and texture stuff

y2% = yy2%          'errors on my first version
y3% = yy3%          'Sorry Alan  ;*)
x1% = xx1%
x2% = xx2%
x3% = xx3%
c1% = Cc1%
c2% = Cc2%
c3% = Cc3%

''''Take a guess... ;*)
IF y1% > y2% THEN SWAP y1%, y2%: SWAP x1%, x2%: SWAP c1%, c2%
IF y1% > y3% THEN SWAP y1%, y3%: SWAP x1%, x3%: SWAP c1%, c3%
IF y2% > y3% THEN SWAP y2%, y3%: SWAP x2%, x3%: SWAP c2%, c3%

'       (1)
'      /   \
'    (2)
'         \  (3)

' need to check for divide by zero - Not any more!
' get double the difference refunded back, that's right
' double the difference ......... GUARANTEED!

'Rel's notes:
'INTERPOLATION
'f(X) = A + X*((B-A)/steps),
'where we slide from A to B in steps and
'f'(X) (the derivative of f(X)), the growing speed of
'f(X) that is, is (B-A)/steps.

'so....
'A=xx1 or clr1  'depends on what you wan't to interpolate
'B=xx2 or clr2  'depends on what you wan't to interpolate
'Xdiff=Steps
'Dc&=(B-A)/Steps or F'(x)
'We won't use X*Dc& as we are adding inside the loop.
'Fun fact!!! Multiplication is just a series of addition. ;*)
'The *65536 is just what we call fixpoint math.

ydiffa% = y2% - y1%         'Steps like morphing
IF ydiffa% THEN
d1& = ((x2% - x1%) * 65536) \ ydiffa%  '
gd1& = ((c2% - c1%) * 65536) \ ydiffa%
END IF

'Ditto
ydiffb% = y3% - y2%
IF ydiffb% THEN
d2& = ((x3% - x2%) * 65536) \ ydiffb%
gd2& = ((c3% - c2%) * 65536) \ ydiffb%
END IF

'Ditto
ydiffc% = y3% - y1%
IF ydiffc% THEN
d3& = ((x3% - x1%) * 65536) \ ydiffc%
gd3& = ((c3% - c1%) * 65536) \ ydiffc%
END IF

lx& = x1% * 65536
rx& = x1% * 65536

lc& = c1% * 65536
rc& = lc&

'Draw Hline interpolated between LC and RC
FOR Y% = y1% TO y2% - 1
HLine (lx& \ 65536), (rx& \ 65536), Y%, (lc&), (rc&)
lx& = lx& + d1&
rx& = rx& + d3&
lc& = lc& + gd1&
rc& = rc& + gd3&
NEXT
' HERE d1 has been added (y2%-y1%)+1 times to lx  = x2
'      d3 has been added (y2%-y1%)+1 times to rx

lx& = (x2% * 65536)     ' NOT NEEDED (for accuracy only)
lc& = c2% * 65536        ' NOT NEEDED (for accuracy only)

FOR Y% = y2% TO y3%
HLine (lx& \ 65536), (rx& \ 65536), Y%, (lc&), (rc&)
lx& = lx& + d2&
rx& = rx& + d3&
lc& = lc& + gd2&
rc& = rc& + gd3&
NEXT Y%

END SUB

SUB Tritexture (textseg%, xx1%, yy1%, uu1%, vv1%, xx2%, yy2%, uu2%, vv2%, xx3%, yy3%, uu3%, vv3%)
'Generic's
'Rels Note: I emulated the BYVAL parameter passing since I was getting errors
'in the Gouraud and texture stuff
'CHECK OUT THE COMMENTW IN TRIGOURAUD AS THEY ARE BASICALLY THE
'SAME. Check for a more detailed info on the module level.
'And of course, how to calc U and V in 3d.

x1% = xx1%
y1% = yy1%
u1% = uu1%
v1% = vv1%

x2% = xx2%
y2% = yy2%
u2% = uu2%
v2% = vv2%

x3% = xx3%
y3% = yy3%
u3% = uu3%
v3% = vv3%

DEF SEG = textseg%
'LINE (x1%, y1%)-(x2%, y2%), 2    '  triangle outline
'LINE (x2%, y2%)-(x3%, y3%), 2    '
'LINE (x3%, y3%)-(x1%, y1%), 2    '

IF y1% > y2% THEN SWAP y1%, y2%: SWAP x1%, x2%: SWAP u1%, u2%: SWAP v1%, v2%
IF y1% > y3% THEN SWAP y1%, y3%: SWAP x1%, x3%: SWAP u1%, u3%: SWAP v1%, v3%
IF y2% > y3% THEN SWAP y2%, y3%: SWAP x2%, x3%: SWAP u2%, u3%: SWAP v2%, v3%

'       (1)
'      /   \
'    (2)
'         \  (3)

' need to check for divide by zero - Not any more!
' get double the difference refunded back, that's right
' double the difference ......... GUARANTEED!

d1& = 0: dg1 = 0

ydiffa% = y2% - y1%
IF ydiffa% THEN
d1& = ((x2% - x1%) * 65536) \ ydiffa%
ud1& = ((u2% - u1%) * 65536) \ ydiffa%
vd1& = ((v2% - v1%) * 65536) \ ydiffa%
END IF

ydiffb% = y3% - y2%
IF ydiffb% THEN
d2& = ((x3% - x2%) * 65536) \ ydiffb%
ud2& = ((u3% - u2%) * 65536) \ ydiffb%
vd2& = ((v3% - v2%) * 65536) \ ydiffb%
END IF

ydiffc% = y3% - y1%
IF ydiffc% THEN
d3& = ((x3% - x1%) * 65536) \ ydiffc%
ud3& = ((u3% - u1%) * 65536) \ ydiffc%
vd3& = ((v3% - v1%) * 65536) \ ydiffc%
END IF

lx& = x1% * 65536
rx& = x1% * 65536

lu& = u1% * 65536: ru& = lu&
lv& = v1% * 65536: rv& = lv&

FOR Y% = y1% TO y2% - 1
HTLine (lx& \ 65536), (rx& \ 65536), Y%, (lu&), (ru&), (lv&), (rv&)
lx& = lx& + d1&
rx& = rx& + d3&
lu& = lu& + ud1&
ru& = ru& + ud3&
lv& = lv& + vd1&
rv& = rv& + vd3&
NEXT

lx& = (x2% * 65536)
lu& = u2% * 65536
lv& = v2% * 65536

' HERE d1 has been added (y2%-y1%)+1 times to lx  = x2
'      d3 has been added (y2%-y1%)+1 times to rx

FOR Y% = y2% TO y3%

HTLine (lx& \ 65536), (rx& \ 65536), Y%, (lu&), (ru&), (lv&), (rv&)

lx& = lx& + d2&
rx& = rx& + d3&
lu& = lu& + ud2&
ru& = ru& + ud3&
lv& = lv& + vd2&
rv& = rv& + vd3&
NEXT Y%

END SUB

/[code]

I thought you might also like this:
A Flat Filler that I converted NOT to use Fixed point so you might understand it well.

SetVideoSeg by Plasma357...

[code]

DECLARE SUB AF.Print (Xpos%, Ypos%, Text\$, Col%)
DECLARE SUB CalcNormals (Model() AS ANY, ModelConnect() AS ANY, V() AS ANY)
DECLARE SUB FlatTri (x1%, y1%, x2%, y2%, x3%, y3%, Col%)
DECLARE SUB DrawCube (Model() AS ANY, Vector() AS ANY)
DECLARE SUB LoadCube (Model() AS ANY, Vector() AS ANY)
DECLARE SUB SetVideoSeg (Segment%)
DECLARE SUB RotateAndProject (Model() AS ANY, AngleX%, AngleY%, AngleZ%)
DECLARE SUB RotNormals (V() AS ANY, V2() AS ANY, AngleX%, AngleY%, AngleZ%)
DEFINT A-Z
REM \$DYNAMIC

TYPE Point3d
X       AS SINGLE                   'Normal 3d coords
Y       AS SINGLE
Z       AS SINGLE
Xr      AS SINGLE
Yr      AS SINGLE
Zr      AS SINGLE
ScrX    AS INTEGER                  'Translated and projected
ScrY    AS INTEGER                  '2d Coords
END TYPE

TYPE PolyType
p1      AS INTEGER
p2      AS INTEGER
p3      AS INTEGER
Clr1    AS INTEGER
Clr2    AS INTEGER
Clr3    AS INTEGER
END TYPE

TYPE VectorType
X      AS SINGLE
Y      AS SINGLE
Z      AS SINGLE
END TYPE

CONST LENS = 256                            'Z
CONST XCENTER = 160                         '??
CONST YCENTER = 100                         '??

CONST PI = 3.14151693#

REDIM SHARED Vpage(32009)  AS INTEGER
DIM SHARED LCOS(359) AS SINGLE
DIM SHARED LSIN(359) AS SINGLE

REDIM SHARED CubeModel(1) AS Point3d
REDIM SHARED CubePoly(1) AS PolyType
REDIM SHARED CubeNormal(1) AS VectorType
REDIM SHARED CubeNormal2(1) AS VectorType
DIM SHARED ThetaX, ThetaY, ThetaZ
DIM SHARED Zcenter, CamX, CamY
DIM SHARED LightNormal AS VectorType

'PreCalc sin and cos lookuptable

FOR I = 0 TO 359
A! = I * PI / 180
LCOS(I) = COS(A!)
LSIN(I) = SIN(A!)
NEXT I

LightNormal.X = 0               'Light is from the camera
LightNormal.Y = 0
LightNormal.Z = -1

RotateAndProject CubeModel(), ThetaX, ThetaY, ThetaZ
CalcNormals CubeModel(), CubePoly(), CubeNormal()

CLS
SCREEN 13
RANDOMIZE TIMER

'Grey Scale the Palette
FOR I = 0 TO 255
OUT &H3C8, I
OUT &H3C9, (I \ 4)
OUT &H3C9, (I \ 4) * .9
OUT &H3C9, (I \ 4) * .1
NEXT I

ThetaX = 0
ThetaY = 0
ThetaZ = 0
Zcenter = LENS

Vpage(6) = 2560
Vpage(7) = 200
Layer = VARSEG(Vpage(0)) + 1
SetVideoSeg Layer

DO

ThetaX = (ThetaX + 1) MOD 360
ThetaY = (ThetaY + 1) MOD 360
ThetaZ = (ThetaZ + 1) MOD 360

RotateAndProject CubeModel(), ThetaX, ThetaY, ThetaZ
RotNormals CubeNormal(), CubeNormal2(), ThetaX, ThetaY, ThetaZ
SetVideoSeg Layer
LINE (0, 0)-(319, 199), 0, BF
DrawCube CubeModel(), CubePoly()
SetVideoSeg &HA000
PUT (0, 0), Vpage(6), PSET

LOOP UNTIL INKEY\$ <> ""

END

'numPoints
NumPoints:
DATA 8

'vertices of Cube
VertexData:
DATA -50,50,50
DATA 50,50,50
DATA 50,50,-50
DATA -50,50,-50
DATA -50,-50,50
DATA 50,-50,50
DATA 50,-50,-50
DATA -50,-50,-50

NumPoly:
DATA 12
ConnectData:
DATA 5,4,0, 5,0,1
DATA 6,2,3, 3,7,6
DATA 6,5,1, 6,1,2
DATA 7,0,4, 7,3,0
DATA 6,7,4, 6,4,5
DATA 0,3,2, 1,0,2

REM \$STATIC
SUB AF.Print (Xpos%, Ypos%, Text\$, Col%)
'Prints the standard 8*8 CGA font
'Paramenters:
'Segment=the Layer to print to
'Xpos,Ypos=the coordinates of the text
'Text\$=the string to print
'col= is the color to print(gradient)

X% = Xpos%
Y% = Ypos%
Spacing% = 8
FOR I% = 0 TO LEN(Text\$) - 1
X% = X% + Spacing%
Offset% = 8 * ASC(MID\$(Text\$, I% + 1, 1)) + 14
FOR J% = 0 TO 7
DEF SEG = &HFFA6
Bit% = PEEK(Offset% + J%)
IF Bit% AND 1 THEN PSET (X%, Y% + J%), Col% + J%
IF Bit% AND 2 THEN PSET (X% - 1, Y% + J%), Col% + J%
IF Bit% AND 4 THEN PSET (X% - 2, Y% + J%), Col% + J%
IF Bit% AND 8 THEN PSET (X% - 3, Y% + J%), Col% + J%
IF Bit% AND 16 THEN PSET (X% - 4, Y% + J%), Col% + J%
IF Bit% AND 32 THEN PSET (X% - 5, Y% + J%), Col% + J%
IF Bit% AND 64 THEN PSET (X% - 6, Y% + J%), Col% + J%
IF Bit% AND 128 THEN PSET (X% - 7, Y% + J%), Col% + J%
NEXT J%
NEXT I%

END SUB

SUB CalcNormals (Model() AS Point3d, ModelConnect() AS PolyType, V() AS VectorType)

FOR I = 1 TO UBOUND(V)

p1 = ModelConnect(I).p1
p2 = ModelConnect(I).p2
p3 = ModelConnect(I).p3
x1 = Model(p1).X
x2 = Model(p2).X
x3 = Model(p3).X
y1 = Model(p1).Y
y2 = Model(p2).Y
y3 = Model(p3).Y
Z1 = Model(p1).Z
Z2 = Model(p2).Z
Z3 = Model(p3).Z

ax! = x2 - x1
bx! = x3 - x2
ay! = y2 - y1
by! = y3 - y2
az! = Z2 - Z1
bz! = Z3 - Z2

'Cross product
xnormal! = ay! * bz! - az! * by!
ynormal! = az! * bx! - ax! * bz!
Znormal! = ax! * by! - ay! * bx!

'Normalize
Mag! = SQR(xnormal! ^ 2 + ynormal! ^ 2 + Znormal! ^ 2)
IF Mag! <> 0 THEN
xnormal! = xnormal! / Mag!
ynormal! = ynormal! / Mag!
Znormal! = Znormal! / Mag!
END IF

IF Znormal! < -1 THEN
Znormal! = -1
ELSEIF Znormal! > 1 THEN
Znormal! = 1
END IF

IF xnormal! < -1 THEN
xnormal! = -1
ELSEIF xnormal! > 1 THEN
xnormal! = 1
END IF

IF ynormal! < -1 THEN
yxnormal! = -1
ELSEIF ynormal! > 1 THEN
ynormal! = 1
END IF

V(I).X = xnormal!
V(I).Y = ynormal!
V(I).Z = Znormal!

NEXT I
END SUB

SUB DrawCube (Model() AS Point3d, Poly() AS PolyType) STATIC

FOR I = 1 TO UBOUND(Poly)
x1 = Model(Poly(I).p1).ScrX       'Get triangles from "projected"
x2 = Model(Poly(I).p2).ScrX       'X and Y coords since Znormal
x3 = Model(Poly(I).p3).ScrX       'Does not require a Z coord
y1 = Model(Poly(I).p1).ScrY       'V1= Point1 connected to V2 then
y2 = Model(Poly(I).p2).ScrY       'V2 to V3 and so on...
y3 = Model(Poly(I).p3).ScrY

'Use the Znormal,the Ray perpendicular(Orthogonal) to the XY plane
'Defined by the Triangle (X1,Y1,X2,Y2,X3,Y3)
'if Less(<) 0 then its facing in the opposite direction so
'don't plot. If =>0 then its facing towards you so Plot.
Znormal = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)
IF Znormal < 0 THEN
nx! = CubeNormal2(I).X
ny! = CubeNormal2(I).Y
nz! = CubeNormal2(I).Z
lx! = LightNormal.X
ly! = LightNormal.Y
lz! = LightNormal.Z
Dot! = (nx! * lx!) + (ny! * ly!) + (nz! * lz!)
IF Dot! < 0 OR Dot! > 1 THEN
Dot! = 0
END IF
Clr = Dot! * 255
C1 = Poly(I).Clr1
C2 = Poly(I).Clr2
C3 = Poly(I).Clr3
FlatTri x1, y1, x2, y2, x3, y3, Clr
END IF

NEXT I

END SUB

SUB FlatTri (x1%, y1%, x2%, y2%, x3%, y3%, Col%)
'Generic's sub
'Modified to use floats so it's be more understandable

LINE (x1%, y1%)-(x2%, y2%), Col%    '  triangle outline
LINE (x2%, y2%)-(x3%, y3%), Col%    '
LINE (x3%, y3%)-(x1%, y1%), Col%    '

IF y1% > y2% THEN SWAP y1%, y2%: SWAP x1%, x2%
IF y1% > y3% THEN SWAP y1%, y3%: SWAP x1%, x3%
IF y2% > y3% THEN SWAP y2%, y3%: SWAP x2%, x3%

' need to check for divide by zero..

ydiffa% = y2% - y1%
IF ydiffa% THEN d1! = ((x2% - x1%)) / ydiffa%

ydiffb% = y3% - y2%
IF ydiffb% THEN d2! = ((x3% - x2%)) / ydiffb%

ydiffc% = 1 + y3% - y1%
IF ydiffc% THEN d3! = ((x3% - x1%)) / ydiffc%

lx! = x1%
rx! = x1%

FOR Y% = y1% TO y2% - 1
LINE (lx!, Y%)-(rx!, Y%), Col%
lx! = lx! + d1!
rx! = rx! + d3!
NEXT

lx! = x2%

FOR Y% = y2% TO y3%
LINE (lx!, Y%)-(rx!, Y%), Col%
lx! = lx! + d2!
rx! = rx! + d3!
NEXT Y%

END SUB

SUB LoadCube (Model() AS Point3d, Tri() AS PolyType) STATIC

RESTORE NumPoints
REDIM Model(1 TO MaxVertex) AS Point3d

RESTORE VertexData
FOR V = 1 TO UBOUND(Model)
Model(V).X = Xt
Model(V).Y = Yt
Model(V).Z = Zt
NEXT V

RESTORE NumPoly
REDIM Tri(MaxPoly) AS PolyType

RESTORE ConnectData

FOR V = 1 TO UBOUND(Tri)
Tri(V).p1 = T1 + 1
Tri(V).p2 = T2 + 1
Tri(V).p3 = T3 + 1
Tri(V).Clr1 = 50 + INT(RND * 100)
NEXT V

REDIM CubeNormal(1 TO UBOUND(Tri)) AS VectorType
REDIM CubeNormal2(1 TO UBOUND(Tri)) AS VectorType

END SUB

SUB RotateAndProject (Model() AS Point3d, AngleX, AngleY, AngleZ) STATIC

'Precalculate the SIN and COS of each angle
CX! = LCOS(AngleX)
SX! = LSIN(AngleX)
CY! = LCOS(AngleY)
SY! = LSIN(AngleY)
CZ! = LCOS(AngleZ)
SZ! = LSIN(AngleZ)

'Transformation matrix formula
'This is actually 16(or 12) equations but I pared it down to 9
'since TX4=0,TY4=0,TZ4=0,13 to 16th =0,0,0,1 (yes Doom!!!)

TX1! = CY! * CZ!
TX2! = CY! * SZ!
TX3! = -SY!
TY1! = CX! * -SZ! + SX! * SY! * CZ!
TY2! = CX! * CZ! + SX! * SY! * SZ!
TY3! = SX! * CY!
TZ1! = -SX! * -SZ! + CX! * SY! * CZ!
TZ2! = -SX! * CZ! + CZ! * SY! * SZ!
TZ3! = CX! * CY!

FOR I = 1 TO UBOUND(Model)

X! = Model(I).X       'Load Original model
Y! = Model(I).Y
Z! = Model(I).Z

RotX! = (X! * TX1! + Y! * TY1! + Z! * TZ1!)
RotY! = (X! * TX2! + Y! * TY2! + Z! * TZ2!)
RotZ! = (X! * TX3! + Y! * TY3! + Z! * TZ3!)

Model(I).Xr = RotX!
Model(I).Yr = RotY!
Model(I).Zr = RotZ!

'Project
Distance% = (LENS - RotZ!)
IF Distance% THEN
Model(I).ScrX = (Zcenter * RotX! / Distance%) + XCENTER + CamX
Model(I).ScrY = -(Zcenter * RotY! / Distance%) + YCENTER + CamY
ELSE
END IF
NEXT I

END SUB

SUB RotNormals (V() AS VectorType, V2() AS VectorType, AngleX, AngleY, AngleZ)

'Precalculate the SIN and COS of each angle
CX! = LCOS(AngleX)
SX! = LSIN(AngleX)
CY! = LCOS(AngleY)
SY! = LSIN(AngleY)
CZ! = LCOS(AngleZ)
SZ! = LSIN(AngleZ)

'Transformation matrix formula
'This is actually 16(or 12) equations but I pared it down to 9
'since TX4=0,TY4=0,TZ4=0,13 to 16th =0,0,0,1 (yes Doom!!!)

TX1! = CY! * CZ!
TX2! = CY! * SZ!
TX3! = -SY!
TY1! = CX! * -SZ! + SX! * SY! * CZ!
TY2! = CX! * CZ! + SX! * SY! * SZ!
TY3! = SX! * CY!
TZ1! = -SX! * -SZ! + CX! * SY! * CZ!
TZ2! = -SX! * CZ! + CZ! * SY! * SZ!
TZ3! = CX! * CY!

FOR I = 1 TO UBOUND(V)

X! = V(I).X       'Load Original vector
Y! = V(I).Y
Z! = V(I).Z

RotX! = (X! * TX1! + Y! * TY1! + Z! * TZ1!)
RotY! = (X! * TX2! + Y! * TY2! + Z! * TZ2!)
RotZ! = (X! * TX3! + Y! * TY3! + Z! * TZ3!)

IF RotZ! < -1 THEN
RotZ! = -1
ELSEIF RotZ! > 1 THEN
RotZ! = 1
END IF

IF RotX! < -1 THEN
RotX! = -1
ELSEIF RotX! > 1 THEN
RotX! = 1
END IF

IF RotY! < -1 THEN
RotY! = -1
ELSEIF RotY! > 1 THEN
RotY! = 1
END IF

V2(I).X = RotX!
V2(I).Y = RotY!
V2(I).Z = RotZ!
NEXT I

END SUB

SUB SetVideoSeg (Segment) STATIC

DEF SEG

IF VideoAddrOff& = 0 THEN ' First time the sub is called

' We need to find the location of b\$AddrC, which holds the graphics
' offset (b\$OffC) and segment (b\$SegC). Since b\$AddrC is in the default
' segment, we can find it by setting it to a certain value, and then
' searching for that value.

SCREEN 13 ' Set b\$SegC to A000 (00A0 in memory)
PSET (160, 100), 0 ' Set b\$OffC to 7DA0 (not needed in the IDE)

FOR Offset& = 0 TO 32764 ' Search for b\$AddrC, which is
IF PEEK(Offset&) = &HA0 THEN ' in the default segment and
IF PEEK(Offset& + 1) = &H7D THEN ' should have a value of
IF PEEK(Offset& + 2) = &H0 THEN ' A0 7D 00 A0.
IF PEEK(Offset& + 3) = &HA0 THEN
VideoAddrOff& = Offset& + 2 ' If we found it, record the
EXIT FOR ' offset of b\$SegC and quit
END IF ' looking. (Oddly, changing
END IF ' the b\$OffC doesn't seem to
END IF ' do anything, so this is why
END IF ' this sub only changes b\$SegC)
NEXT

END IF

' Change b\$SegC to the specified Segment

POKE VideoAddrOff& + 1, (Segment AND &HFF00&) \ &H100

END SUB

[/code]
 Logged

y smiley is 24 bit.

Genso's Junkyard:
http://rel.betterwebber.com/
Jark
Ancient Guru

Posts: 566

 « Reply #26 on: May 30, 2003, 12:32:47 AM »

You may have notived I have a different 3D approach in my progs: slow, but Hi-Res. My question about triangles was just a "request for confirmation" :wink:
 Logged

hink Global, Make Symp' All ! ®
relsoft
*/-\*

Posts: 3927

 « Reply #27 on: May 30, 2003, 12:39:47 AM »

Quote from: "Jark"
You may have notived I have a different 3D approach in my progs: slow, but Hi-Res. My question about triangles was just a "request for confirmation" :wink:

My views:

Realtime3d=Polygon fillers

Stills 3d=Raytracing

They are a lot different. Though I saw Toshi's very fast realtime raytracer. Dang! its cool!!!
 Logged

y smiley is 24 bit.

Genso's Junkyard:
http://rel.betterwebber.com/
Ninkazu
Been there, done that

Posts: 1169

 « Reply #28 on: May 30, 2003, 01:09:22 AM »

Thanks Rel, I get out of school tomorrow, so I'll take a look at it then. It's way past my konking out time.
 Logged

am an asshole. Get used to it.
Antoni Gual
Na_th_an

Posts: 1434

 « Reply #29 on: May 30, 2003, 11:19:53 AM »

Jark is the only guy in the world doing 3d without any triangles: all his demos in TClib are calculated pixel by pixel...
 Logged

Antoni
 Pages: 1 [2] 3 4