Qbasicnews.com
February 26, 2020, 01:21:44 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: 1 [2] 3 4
  Print  
Author Topic: Triangle routine gone haywire  (Read 10519 times)
relsoft
*/-\*
*****
Posts: 3927



WWW
« 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



WWW
« 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%)
  'DRAWS TRIANGLE WITH FLAT SHADING
  '
  '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



WWW
« 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 Tongue
Logged

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



WWW
« 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



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

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

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



WWW
« 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



WWW
« 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



WWW
« 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



WWW
« 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.

Please, help me quitting stupidness...
Logged

hink Global, Make Symp' All !
Ninkazu
Been there, done that
*****
Posts: 1169



WWW
« 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



WWW
« 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


'//// Gouraud Shading....
'//// 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
   '=Ad-BC
   
   '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&)
'Generic's routine..Used in Gouraud Shading
'Rels Note: I emulated the BYVAL parameter passing since I was getting errors
         'in the Gouraud and texture stuff
      'I also added some comments ;*)

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
      'See the comments in HLine

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


y1% = yy1%          'Added this since swapping stuff made some
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!
' call me mad! find more madness elsewhere for less and
' 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!
' call me mad! find more madness elsewhere for less and
' 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

LoadCube CubeModel(), CubePoly()
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
READ MaxVertex
REDIM Model(1 TO MaxVertex) AS Point3d


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

RESTORE NumPoly
READ MaxPoly
REDIM Tri(MaxPoly) AS PolyType

RESTORE ConnectData

FOR V = 1 TO UBOUND(Tri)
        READ T1, T2, T3
        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&, Segment AND &HFF
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



WWW
« 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



WWW
« 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



WWW
« 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



WWW
« 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
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!