home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TUT08NEW.ZIP / TUT8.TXT < prev   
Text File  |  1995-01-14  |  18KB  |  381 lines

  1.                    ╒═══════════════════════════════╕
  2.                    │         W E L C O M E         │
  3.                    │  To the VGA Trainer Program   │ │
  4.                    │              By               │ │
  5.                    │      DENTHOR of ASPHYXIA      │ │ │
  6.                    │      (updated by Snowman)     │ │ │
  7.                    ╘═══════════════════════════════╛ │ │
  8.                      ────────────────────────────────┘ │
  9.                        ────────────────────────────────┘
  10.  
  11.                            --==[ PART 8 ]==--
  12.  
  13.  
  14. [Note: things in brackets have been added by Snowman.  The original text
  15. has remained mostly unaltered except for the inclusion of C++ material]
  16.  
  17. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  18. ■ Introduction
  19.  
  20. Hello everybody! Christmas is over, the last of the chocolates have been
  21. eaten, so it's time to get on with this, the eighth part of the ASPHYXIA
  22. Demo Trainer Series. This particular part is primarily about 3-D, but
  23. also includes a bit on optimisation.
  24.  
  25. If you are already a 3-D guru, you may as well skip this text file, have
  26. a quick look at the sample program then go back to sleep, because I am
  27. going to explain in minute detail exactly how the routines work ;)
  28.  
  29. If you would like to contact me, or the team, there are many ways you
  30. can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
  31.                   on the ASPHYXIA BBS.
  32.             2) Write a message in the Programming conference on the
  33.                   For Your Eyes Only BBS (of which I am the Moderator )
  34.                   This is preferred if you have a general programming query
  35.                   or problem others would benefit from.
  36.             4) Write to Denthor, EzE or Goth on Connectix.
  37.             5) Write to :  Grant Smith
  38.                            P.O.Box 270 Kloof
  39.                            3640
  40.                            Natal
  41.             6) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
  42.                   call during varsity)
  43.             7) Write to mcphail@beastie.cs.und.ac.za on InterNet, and
  44.                   mention the word Denthor near the top of the letter.
  45.  
  46. NB : If you are a representative of a company or BBS, and want ASPHYXIA
  47.        to do you a demo, leave mail to me; we can discuss it.
  48. NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
  49.         quite lonely and want to meet/help out/exchange code with other demo
  50.         groups. What do you have to lose? Leave a message here and we can work
  51.         out how to transfer it. We really want to hear from you!
  52.  
  53.  
  54.  
  55. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  56. ■ Optimisation
  57.  
  58. Before I begin with the note on 3-D, I would like to stress that many of
  59. these routines, and probably most of your own, could be sped up quite a
  60. bit with a little optimisation. One must realise, however, that you must
  61. take a look at WHAT to optimise ... converting a routine that is only
  62. called once at startup into a tightly coded assembler routine may show
  63. off your merits as a coder, but does absolutely nothing to speed up your
  64. program. Something that is called often per frame is something that
  65. needs to be as fast as possible. For some, a much used procedure is the
  66. PutPixel procedure. Here is the putpixel procedure I gave you last week:
  67.  
  68. [Note: Snowman here!  I consulted the official Intel documentation and
  69. noticed that Denthor is basing the clock ticks on the 8088 processor and
  70. not the 286, 386, or 486 processors.  I have taken the time to include
  71. the information for these other processors.]
  72.  
  73. Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
  74.  
  75. BEGIN                                 -clock ticks-
  76.   Asm                               8088 286 386 486
  77.     push    ds                       14   3   2   3
  78.     push    es                       14   3   2   3
  79.     mov     ax,[where]                8   5   4   1
  80.     mov     es,ax                     2   2   2   3
  81.     mov     bx,[X]                    8   5   4   1
  82.     mov     dx,[Y]                    8   5   4   1
  83.     push    bx                       15   3   2   1
  84.     mov     bx, dx                    2   2   2   1
  85.     mov     dh, dl                    2   2   2   1
  86.     xor     dl, dl                    3   2   2   1
  87.     shl     bx, 1                     2   2   3   3
  88.     shl     bx, 1                     2   2   3   3
  89.     shl     bx, 1                     2   2   3   3
  90.     shl     bx, 1                     2   2   3   3
  91.     shl     bx, 1                     2   2   3   3
  92.     shl     bx, 1                     2   2   3   3
  93.     add     dx, bx                    3   2   2   1
  94.     pop     bx                       12   5   4   4
  95.     add     bx, dx                    3   2   2   1
  96.     mov     di, bx                    2   2   2   3
  97.     xor     al,al                     3   2   2   1
  98.     mov     ah, [Col]                 8   5   4   1
  99.     mov     es:[di],ah               10   3   2   1
  100.     pop     es                       12   5   7   3
  101.     pop     ds                       12   5   7   3
  102.   End;                              ---------------
  103. END;                                153  75  76  52 Total ticks
  104.  
  105. NOTE : Don't take my clock ticks as gospel, I probably got one or two
  106.        wrong.
  107.  
  108. Right, now for some optimising. Firstly, if you have 286 instructions
  109. turned on, you may replace the 6 shl,1 with shl,6. Secondly, the Pascal
  110. compiler automatically pushes and pops ES, so those two lines may be
  111. removed. DS:[SI] is not altered in this procedure, so we may remove
  112. those too. Also, instead of moving COL into ah, we move it into AL and
  113. call stosb (es:[di]:=al; inc di). Let's have a look at the routine now :
  114.  
  115.  
  116. Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
  117. BEGIN                                 -clock ticks-
  118.   Asm                               8088 286 386 486
  119.     mov     ax,[where]                8   5   4   1
  120.     mov     es,ax                     2   2   2   3
  121.     mov     bx,[X]                    8   5   4   1
  122.     mov     dx,[Y]                    8   5   4   1
  123.     push    bx                       15   3   2   1
  124.     mov     bx, dx                    2   2   2   1
  125.     mov     dh, dl                    2   2   2   1
  126.     xor     dl, dl                    3   2   2   1
  127.     shl     bx, 6                     8  11   3   2
  128.     add     dx, bx                    3   2   2   1
  129.     pop     bx                       12   5   4   4
  130.     add     bx, dx                    3   2   2   1
  131.     mov     di, bx                    2   2   2   3
  132.     mov     al, [Col]                 8   5   4   1
  133.     stosb                            11   3   4   5
  134.   End;                             ----------------
  135. END;                                 95  56  43  27 Total ticks
  136.  
  137. Now, let us move the value of BX directly into DI, thereby removing a
  138. costly push and pop. The MOV and the XOR of DX can be replaced by it's
  139. equivalent, SHL DX,8
  140.  
  141. [Note: If you are running on a 286, this last set of optimizations
  142. actually makes the routine slower!  On a 286, an "SHL" takes 5 ticks
  143. plus the number you are moving by.  For example: an "SHL AX,6" would
  144. take 11 clock ticks (5 ticks for SHL and 6 clock ticks for the "6"
  145. part of the expression.]
  146.  
  147. Procedure Putpixel (X,Y : Integer; Col : Byte; where:word); assembler;
  148.  
  149. BEGIN                                 -clock ticks-
  150. asm                                 8088 286 386 486
  151.     mov     ax,[where]                8   5   4   1
  152.     mov     es,ax                     2   2   2   3
  153.     mov     bx,[X]                    8   5   4   1
  154.     mov     dx,[Y]                    8   5   4   1
  155.     mov     di,bx                     2   2   2   3
  156.     mov     bx, dx                    2   2   2   1
  157.     shl     dx, 8                     8  13   3   2
  158.     shl     bx, 6                     8  11   3   2
  159.     add     dx, bx                    3   2   2   1
  160.     add     di, dx                    3   2   2   1
  161.     mov     al, [Col]                 8   5   4   1
  162.     stosb                            11   3   4   5
  163. end;                               ----------------
  164.                                      71  57  36  22 Total ticks
  165.  
  166. As you can see, we have brought the clock ticks down from 153-52 (8088-486)
  167. ticks to 71-22 (8088-486) ticks ... quite an improvement. (The current
  168. ASPHYXIA putpixel takes 48 clock ticks) . As you can see, by going through
  169. your routines a few times, you can spot and remove unnecessary instructions,
  170. thereby greatly increasing the speed of your program.
  171.  
  172.  
  173. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  174. ■ Defining a 3-D object
  175.  
  176. Drawing an object in 3-D is not that easy. Sitting down and plotting a
  177. list of X,Y and Z points can be a time consuming business. So, let us
  178. first look at the three axes you are drawing them on :
  179.  
  180.                     Y    Z
  181.                    /|\  /
  182.                     | /
  183.              X<-----|----->
  184.                     |
  185.                    \|/
  186.  
  187. X is the horisontal axis, from left to right. Y is the vertical axis,
  188. from top to bottom. Z is the depth, going straight into the screen.
  189.  
  190. In this trainer, we are using lines, so we define 2 X,Y and Z
  191. coordinates, one for each end of the line. A line from far away, in the
  192. upper left of the X and Y axes, to close up in the bottom right of the
  193. X and Y axes, would look like this :
  194.  
  195. {       x1 y1  z1   x2  y2 z2    }
  196.     ( (-10,10,-10),(10,-10,10) )
  197.  
  198.  
  199. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  200. ■ Rotating a point with matrixes
  201.  
  202. NOTE : I thought that more then one matix are matrisese (sp), but my 
  203.        spellchecker insists it is matrixes, so I let it have it's way 
  204.        ;-)
  205.  
  206. Having a 3-D object is useless unless you can rotate it some way. For
  207. demonstration purposes, I will begin by working in two dimensions, X and
  208. Y.
  209.  
  210. Let us say you have a point, A,B, on a graph.
  211.                       Y
  212.                       |  /O1 (Cos (a)*A-Sin (a)*B , Sin (a)*A+Cos (a)*B)
  213.                       |/      (A,B)
  214.                X<-----|------O-->
  215.                       |
  216.                       |
  217.  
  218. Now, let us say we rotate this point by 45 degrees anti-clockwise. The
  219. new A,B can be easily be calculated using sin and cos, by an adaption of
  220. our circle algorithm, ie.
  221.            A2:=Cos (45)*A - Sin (45)*B
  222.            B2:=Sin (45)*A + Cos (45)*B
  223. I recall that in standard 8 and 9, we went rather heavily into this in
  224. maths. If you have troubles, fine a 8/9/10 maths book and have a look;
  225. it will go through the proofs etc.
  226.  
  227. Anyway, we have now rotated an object in two dimensions, AROUND THE Z
  228. AXIS. In matrix form, the equation looks like this :
  229.  
  230.    [  Cos (a)   -Sin (a)      0        0     ]    [  x ]
  231.    [  Sin (a)    Cos (a)      0        0     ]  . [  y ]
  232.    [     0         0          1        0     ]    [  z ]
  233.    [     0         0          0        1     ]    [  1 ]
  234.  
  235. I will not go to deeply into matrixes math at this stage, as there are
  236. many books on the subject (it is not part of matric maths, however). To
  237. multiply a matrix, to add the products of the row of the left matrix and
  238. the column of the right matrix, and repeat this for all the columns of the
  239. left matrix. I don't explain it as well as my first year maths lecturer,
  240. but have a look at how I derived A2 and B2 above. Here are the other
  241. matrixes :
  242.  
  243. Matrix for rotation around the Y axis :
  244.    [  Cos (a)      0       -Sin (a)    0     ]    [  x ]
  245.    [     0         1          0        0     ]  . [  y ]
  246.    [  Sin (a)      0        Cos (a)    0     ]    [  z ]
  247.    [     0         0          0        1     ]    [  1 ]
  248.  
  249. Matrix for rotation around the X axis :
  250.    [     1         0                   0     ]    [  x ]
  251.    [     0       Cos (a)   -Sin (a)    0     ]  . [  y ]
  252.    [     0       Sin (a)    Cos (a)    0     ]    [  z ]
  253.    [     0         0          0        1     ]    [  1 ]
  254.  
  255. By putting all these matrixes together, we can translate out 3D points
  256. around the origin of 0,0,0. See the sample program for how we put them
  257. together.
  258.  
  259. In the sample program, we have a constant, never changing base object.
  260. This is rotated into a second variable, which is then drawn. I am sure
  261. many of you can thing of cool ways to change the base object, the
  262. effects of which will appear while the object is rotating. One idea is
  263. to "pulsate" a certain point of the object according to the beat of the
  264. music being played in the background. Be creative. If you feel up to it,
  265. you could make your own version of transformers ;)
  266.  
  267.  
  268.  
  269. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  270. ■ Drawing a 3D point to screen
  271.  
  272. Having a rotated 3D object is useless unless we can draw it to screen.
  273. But how do we show a 3D point on a 2D screen? The answer needs a bit of
  274. explaining. Examine the following diagram :
  275.  
  276.               |         ________-------------
  277.           ____|___------      o Object at X,Y,Z     o1 Object at X,Y,Z2
  278.  Eye -> O)____|___
  279.               |   ------________
  280.               |                 -------------- Field of vision
  281.             Screen
  282.  
  283. Let us pretend that the centre of the screen is the horizon of our
  284. little 3D world. If we draw a three dimensional line from object "o" to
  285. the centre of the eye, and place a pixel on the X and Y coordinates
  286. where it passes through the screen, we will notice that when we do the
  287. same with object o1, the pixel is closer to the horizon, even though
  288. their 3D X and Y coords are identical, but "o1"'s Z is larger then
  289. "o"'s. This means that the further away a point is, the closer to the
  290. horizon it is, or the smaller the object will appear. That sounds
  291. right, doesent it? But, I hear you cry, how do we translate this into a
  292. formula? The answer is quite simple. Divide your X and your Y by your Z.
  293. Think about it. The larger the number you divide by, the closer to zero,
  294. or the horizon, is the result! This means, the bigger the Z, the
  295. further away is the object! Here it is in equation form :
  296.  
  297.   [Pascal]
  298.  
  299.        nx := 256*x div (z-Zoff)+Xoff
  300.        ny := 256*y div (z-Zoff)+Yoff
  301.  
  302.   [C++]
  303.  
  304.        nx =  ((256*x) / (z-Zoff)) + Xoff;
  305.        nx =  ((256*y) / (z-Zoff)) + Yoff;
  306.  
  307.  
  308. NOTE : Zoff is how far away the entire object is, Xoff is the objects X
  309.        value, and Yoff is the objects Y value. In the sample program,
  310.        Xoff start off at 160 and Yoff starts off at 100, so that the
  311.        object is in the middle of the screen.
  312.  
  313. The 256 that you times by is the perspective with which you are viewing.
  314. Changing this value gives you a "fish eye" effect when viewing the
  315. object. Anyway, there you have it! Draw a pixel at nx,ny, and viola! you
  316. are now doing 3D! Easy, wasn't it?
  317.  
  318.  
  319. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  320. ■ Possible improvements
  321.  
  322. This program is not the most optimised routine you will ever encounter
  323. (;-)) ... it uses 12 muls and 2 divs per point. (Asphyxia currently has
  324. 9 muls and 2 divs per point) Real math is used for all the calculations
  325. in the sample program, which is slow, so fixed point math should be
  326. implemented (I will cover fixed point math in a future trainer). The
  327. line routine currently being used is very slow. Chain-4 could be used to
  328. cut down on screen flipping times.
  329.  
  330. Color values per line should be added, base object morphing could be put
  331. in, polygons could be used instead of lines, handling of more then one
  332. object should be implemented, clipping should be added instead of not
  333. drawing something if any part of it is out of bounds.
  334.  
  335. In other words, you have a lot of work ahead of you ;)
  336.  
  337.  
  338. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  339. ■  In closing
  340.  
  341. There are a lot of books out there on 3D, and quite a few sample
  342. programs too. Have a look at them, and use the best bits to create your
  343. own, unique 3D engine, with which you can do anything you want. I am
  344. very interested in 3D (though EzE and Goth wrote most of ASPHYXIA'S 3D
  345. routines), and would like to see what you can do with it. Leave me a
  346. message through one of the means described above.
  347.  
  348. I am delving into the murky world of texture mapping. If anyone out 
  349. there has some routines on the subject and are interested in swapping, 
  350. give me a buzz!
  351.  
  352. What to do in future trainers? Help me out on this one! Are there any
  353. effects/areas you would like a bit of info on? Leave me a message!
  354.  
  355. I unfortunately did not get any messages regarding BBS's that carry this
  356. series, so the list that follows is the same one from last time. Give
  357. me your names, sysops!
  358.  
  359. Aaaaargh!!! Try as I might, I can't think of a new quote. Next time, I
  360. promise! ;-)
  361.  
  362. Bye for now,
  363.   - Denthor
  364.  
  365.  
  366. These fine BBS's carry the ASPHYXIA DEMO TRAINER SERIES : (alphabetical)
  367.  
  368. ╔══════════════════════════╦════════════════╦═════╦═══╦════╦════╗
  369. ║BBS Name                  ║Telephone No.   ║Open ║Msg║File║Past║
  370. ╠══════════════════════════╬════════════════╬═════╬═══╬════╬════╣
  371. ║ASPHYXIA BBS #1           ║(031) 765-5312  ║ALL  ║ * ║ *  ║ *  ║
  372. ║ASPHYXIA BBS #2           ║(031) 765-6293  ║ALL  ║ * ║ *  ║ *  ║
  373. ║Connectix BBS             ║(031) 266-9992  ║ALL  ║ * ║    ║    ║
  374. ║For Your Eyes Only BBS    ║(031) 285-318   ║A/H  ║ * ║ *  ║ *  ║
  375. ╚══════════════════════════╩════════════════╩═════╩═══╩════╩════╝
  376.  
  377. Open = Open at all times or only A/H
  378. Msg  = Available in message base
  379. File = Available in file base
  380. Past = Previous Parts available
  381.