
                     - THE OUTLAW TRIAD DEMO-SERIES -

 PART XV 

                         Written by : Inopia/OT
                         Topics     : More Gouraud & Texture

 Introduction 

 Welcome to the Outlaw Triad demo-series! In these series we will be talking
 about programming demo-effects in either pascal or assembler. Theory behind
 the effects shall be discussed while a full sourcecode is also provided.
 Hey kids, it's Inopia again with a blurry tutor which you are supposed to
 read and be happy about. Well, Vulture has been kicking my ass around about
 a fast way to do texture mapping and gouraud shading so let's talk some more
 about that. OT already released a trainer covering those topics but hey, who
 cares! There's always room for improvement... Here we go!

 Theory 

 - GOURAUD -

 The problem with Gouruad and Texture routines is that a horizontal line rou-
 tine also requires sum heavy interpolation, and that's quite a problem if you
 never coded something like that before (never coded one of those cool texture
 rotating thingies?). But don't let this scare you off, cuz it's really not
 that hard.

 By the way, I advise you to read our other tutor on flat shaded polys, since
 you aught to understand those principles first and I'm NOT going to explain
 that AGAIN! So if you don't have it, login to one of our fine distribution
 points and grab it NOW!

 Anyway, a mistake that a lot of people make, is that they calculate the
 deltavalues needed to draw a horizontal line (of wich your poly is made of),
 every time a new line is drawn. This is not very smart, since an average
 poly is made of, let's say, 7 lines (depends of course), which means, 7
 times a DIV, wich is not very fast. It's also possible to do those deltas
 ONCE PER POLY! I once had an engine, wich did 256 polys smoothly on a p75...
 Boy, that sucked :-) But when I upgraded that one thing, my engine suddenly
 did 1200 polys! (not very fast either, but hey, it's still pascal(-:)

 Well, first let's do Gouraud shading, and we'll upgrade that to do texture
 mapping later on. Gouraud is a shading method, where every vertice has it's
 own color, wich is then interpolated along the polygon. It is quite fast
 compared to environment mapping, but you won't get that cool lightspot.
 Ofcourse you can simulate it, but more of that in the optimizations/tricks
 section. Gouraud polys aren't very different from those flat polys, except
 for the horizontal line routine. Also, they require not only interpolation
 of the edge X coordinates, but also of the colors (but that's obvious). You
 can handle the colors the same as the X coordinates.

 Remember that now every point does not consist of (X,Y), but of (X,Y,C),
 where C is the color of that particular vertice.

 Let's bring up the poly again:


            TOP           -
           / \             |
          /   \            | Loop1
         /     \           |
        /       \          |
       /         \         |
     Q*        /  MID     -
     /      /              |
    /    /                 | Loop2
   /  /                    |
  //                       |
 BOT                      -


 Remember? Well, we need to know point Q, because we need the delta values of
 the longest line in the poly (most accurate), which is always Q.X-MID.X.
 So the first thing we do is calculate point Q. You know Q.Y, because it's
 the same as MID.Y. Therefore:

 Q.Y = MID.Y

 Okay, what else do we know... Well, we know point Q is somewhere on TOP-BOT.
 Actually, we know it's on TOP-BOT at position MID.Y! So we can now calculate
 Q.X and Q.C. Just interpolate. We can use the same deltavalues as the ones we
 used to calculate the edges of the polygon. If you read our tutor on the FLAT
 SHADED POLYGONS (otpoly.zip), you know how to get it. We'll call it EBR here.
 What we need to do is take the distance between TOP.Y and Q.Y, multiply it by
 EBR (the delta), and add top.x:

 Q.X = (TOP.Y-Q.Y) * EBR.X + TOP.X

 This can ofcourse also be done with the color values:

 Q.C = (TOP.Y-Q.Y) * EBR.C + TOP.C

 Note that we now have TWO right edge deltas, one for the X positions, and one
 for the colors. Okay, now that we know point Q, let's put it to use. Let's
 calculate the Delta value for the horizontal line routine thingie. I hope
 that you know how this formula is going to look like by now, but for the
 people who want to be sure, here it is:

 DELTAC = (MID.C - Q.C) / (MID.X - Q.X)

 The last thing we need to do now, is change the HLINE routine. When you are
 going to draw a poly, you interpolate the X and C values along the edges. Now
 you can draw your HLINE. The color of the pixel will be represented by the
 variable C. All you do, is plot a pixel with color C, add DELTAC to C, and
 plot the next pixel. Keep this up the whole line, and voila! You have a nice
 little Gouraud engine running! I know I'm not very good at explaining this
 stuff, so here's a little code:

 For I = X1 to X2 do
   PUTPIXEL(I,YPOS,C)
   ADD C,DELTAC
 Next I

 - TEXTURE MAPPING -

 So... This covers gouraud. Texture mapping isn't very different. Only that
 every vertice has an X, Y, U, and V value. (U,V) are the coordinates on the
 texturemap. Do everything just like gouraud, with the difference that every-
 thing you do to the Color values, you need to do twice (once to U, and once
 to V). The HLINE should look something like this:

 For I = X1 to X2 do
   PUTPIXEL(I,YPOS,MAP[V*256+U])
   ADD U,DELTAU
   ADD V,DELTAV
 Next I

 Optimization/Tricks:

 - GOURAUD -

 - This is about gouraud. With Flatshading, you need colors for a face. With
   gouraud you need colors for every vertice. In the OT file on lightsourcing,
   we've discussed how to get those face-colors. But how to get those vertice
   colors? Well, it's really easy. For every vertice, take the average of
   the colors of all faces using that vertice!
   hint: pre-calculate a vertex normal by taking the average of all face
   normals of the faces using that vertice. Do this for all vertices to get
   all vertex normals. Rotate those vertex normals like you do vertices and
   then take the dotproduct of the rotated vertice normal and your light
   vector to calculate the color of the vertice.
 - Some demos have two vector objects moving through each other. Just check
   out VERSES from EMF. How they did that? Well, it's called Z-BUFFERING.
   You need another buffer (or virtual screen, what's in a name?). Just like
   the colors in gouraud shading, the Z-VALUES are interpolated along the poly,
   and they are stored into that virtual screen (=Z-BUFFER). When you draw the
   next face, you check if the Z value of a particulair pixel is smaller than
   the one already present on the Z-Buffer, and if so you plot (to the screen,
   as well as to the z-buffer).
 - As seen in demos like ARABICUM from MASSIVE, you can also just grab sum
   random values for your vertice colors, and it still looks kinda nice.

 - TEXTURE MAPPING -

 - It's faster to use a 256x256 texturemap instead of something like 320x200.
   The U and V values are interpolated seperately, and when you want to put
   them toghether to get an offset on your texturemap, you get Y*256+X.
   In assembler, this would be

     MOV BH,Y
     MOV BL,X

   Because BH is a significant byte, it's automatically shifted 8 bits, which
   resembles a multiplication by 256.
 - Environment mapping (fake phong). Now that you know how to do some texture
   mapping, you can do environment mapping. For every vertice, grab the average
   of all normalized facenormals of the faces using that vertice and multiply
   by 128 (for 256x256 texturemaps). Then you just rotate those verticenormals
   like vertices. When drawing a poly, the (U,V) coordinates resemble the (X,Y)
   of the rotated verticenormals, +128. The +128 needs to be done, because the
   (U,V) coordinates have to be centered to the middle of your fine 256x256
   texturemap.
 - Lenz mapping (fake refraction?). I got this tip from PHRED (thanx). Just
   normalize the vertices and use the (X,Y) coordinates as (U,V) coordinates
   (don't forget to add 128). It looks kinda lenzy...

 Gosh, I just realized that OT has covered just about every aspect of the 3D
 wizardry... it's time we find another subject!

 Ah yeah, if you know something we could write about, or if you coded a cool
 engine, if you want to puke at us, or whatever, REACH US!! I myself can be
 reached at INOPIA@HORIZON.NL (e-mail) You can also check if I'm at #TRAX or
 #CODERS (irc.demoscene.org & irc.neato.org). Check saturdays and sundays
 around 23:00 and 24:00. And I'm sure VULTURE is going to paste quite a list
 of ways to reach Outlaw Triad.

 Bye,
                -Inopia/OT-

 Distro Sites 

 All our releases are available at these fine boards:

  Amberdawn        World HQ          +31 (010)-2160945
  Excessive force  Dutch Distro      +31 (0497)-572146
  ShockWave        South African HQ  +27 (011)888-6345
  Society HQ       United States HQ  +1  (518)465-6721
  ACe World        Brazilian HQ      +55 (21)-259-8847
  Dark Genesis     Canadian HQ       +1  (250)561-2850    More distros wanted!
  Corps Elite      Canadian Distro   +1  (ITS)-PRIVATE
  Pixel Wars       Italian HQ        +39 (744)-220515
  Power Point      Belgium HQ        +32 (3)-4881033
  LooK BBS         Polish HQ         +48 (94)-415621
  iK BBS           Swedish HQ        +46 (63)-35644

 Also check the major FTP/WWW sites for Outlaw Triad productions.

 Contact 

 Want to contact Outlaw Triad for some reason? Please do so! You can reach
 us at our distrosites in Holland. Or if you have e-mail access, mail us:

   Vulture   (coder/pr)   comma400@tem.nhl.nl
   Inopia    (coder)      inopia@horizon.nl

 Our internet homepage:

   http://www.tem.nhl.nl/~comma400/vulture.html

 All our releases are available at our homepage so if you haven't got all,
 visit us. These internet adresses should be valid at least till june 1997.



            Quote: When you tried everything, read the manual...