home *** CD-ROM | disk | FTP | other *** search
/ The Equalizer BBS / equalizer-bbs-collection_2004.zip / equalizer-bbs-collection / DEMOSCENE-STUFF / PHRO.ZIP / VECTOR.PAS < prev   
Pascal/Delphi Source File  |  1995-12-30  |  14KB  |  412 lines

  1. {   Vector Engine Source File                  }
  2. {   PHRO!                                      }
  3. {   Phred/OTM                                  }
  4. {   achalfin@uceng.uc.edu                      }
  5. {   DO NOT DISTRIBUTE THIS SOURCE FILE         }
  6.  
  7. Unit Vector;
  8.  
  9. Interface
  10.  
  11. Const
  12.   cGouraudPoly = 1;
  13.   cPhongPoly = 2;
  14.  
  15. Procedure InitVectorRoutines(NumtoSort : Integer);
  16. Procedure CloseVectorRoutines;
  17. Procedure SelectEnable(Num, Ena : Byte; EnMap : Pointer);
  18. Procedure Location(Num, tx, ty, tz, ax, ay, az : Longint);
  19. Procedure LoadVectorObject(Data : Pointer; NumVecObjects, Shading : Byte);
  20. Procedure DisplayVectorObjects(VPage : Word);
  21. Procedure FreeVectorObject(Num : Byte);
  22.  
  23. Implementation
  24.  
  25. Uses Polygons;
  26.  
  27. Type
  28.   SCoord = Record     { Screen coordinate                  }
  29.     x, y : Integer;
  30.   End;
  31.   LCoord = Record     { Vertex & Normal coordinate         }
  32.     x, y, z : Longint;
  33.   End;
  34.   PolygonDef = Record
  35.     p1, p2, p3 : Integer;
  36.   End;
  37.   TPolygonList = Array[0..1000] of PolygonDef;
  38.   PPolygonList = ^TPolygonList;
  39.   TCoordList = Array[0..1000] of LCoord;
  40.   PCoordList = ^TCoordList;
  41.   TScreenCoord = Array[0..1000] of SCoord;
  42.   PScreenCoord = ^TScreenCoord;
  43.   PSortRec = ^PhongSortRec;
  44.   PhongSortRec = Record
  45.     ZMid  : Integer;
  46.     PolyType : Byte;
  47.     OwnerIndex : Byte;
  48.     Next  : PSortRec;   { 4 Bytes }
  49.     Index : Integer;    { 2 Bytes }
  50.     Theta1, Phi1  : Byte;  { 2 Bytes }
  51.     Theta2, Phi2  : Byte;  { 2 Bytes }
  52.     Theta3, Phi3  : Byte;  { 2 Bytes }
  53.        { Exactly 16 bytes. For faster indexing }
  54.   End;
  55.   GSortRec = ^GouraudSortRec;
  56.   GouraudSortRec = Record
  57.     ZMid  : Integer;
  58.     PolyType : Byte;
  59.     OwnerIndex : Byte;
  60.     Next  : PSortRec;   { 4 Bytes }
  61.     Index : Integer;    { 2 Bytes }
  62.     C1, C2, C3 : Byte;  { 3 Bytes }
  63.     Base : Byte;
  64.     T1, T2 : Byte;  { 3 Bytes }
  65.        { Exactly 16 bytes. For faster indexing }
  66.   End;
  67.   TRotateList = Array[0..5000] of Byte;
  68.   PRotateList = ^TRotateList;
  69.   TSortList = Array[0..3000] of PhongSortRec;
  70.   PSortList = ^TSortList;
  71.   TByteList = Array[0..255] of PSortRec;
  72.   PByteList = ^TByteList;
  73.   DotRec = Record
  74.     Viewer, XAxis, YAxis : Longint;
  75.   End;
  76.   tVectorObject = Record
  77.     LocalVert  : pCoordList;
  78.     WorldVert  : pCoordList;
  79.     ScreenVert : pScreenCoord;
  80.     Normals    : pCoordList;
  81.     VertNorms  : pCoordList;
  82.     Polygons   : pPolygonList;
  83.     RotateList : pRotateList;
  84.     NumVert    : Integer;
  85.     NumFacet   : Integer;
  86.     ShadeType  : Byte;
  87.     Enabled    : Byte;
  88.     EnvMap     : Pointer;
  89.     xt, yt, zt : Longint;
  90.     xa, ya, za : Word;
  91.     DotList    : Array[0..1000] of DotRec;
  92.   End;
  93.  
  94. Var
  95.   SortList : PSortList;
  96.   VectorObjects : Array[0..3] of tVectorObject;
  97.   ObjectViewer : LCoord;
  98.   XAxis, YAxis : LCoord;
  99.   MSBList : PByteList;
  100.   MaxSort : Integer;
  101.  
  102. Procedure Location(Num, tx, ty, tz, ax, ay, az : Longint);
  103.  
  104. Begin
  105.   VectorObjects[Num].xa := ax;
  106.   VectorObjects[Num].ya := ay;
  107.   VectorObjects[Num].za := az;
  108.   VectorObjects[Num].xt := tx;
  109.   VectorObjects[Num].yt := ty;
  110.   VectorObjects[Num].zt := tz;
  111. End;
  112.  
  113. Procedure InitVectorRoutines(NumtoSort : Integer);
  114.  
  115. Begin
  116.   MaxSort := NumToSort;
  117.   Getmem(SortList, NumToSort*Sizeof(PhongSortRec));
  118.   FillChar(VectorObjects, Sizeof(VectorObjects), 0);
  119. End;
  120.  
  121. Procedure CloseVectorRoutines;
  122.  
  123. Begin
  124.   Freemem(SortList, MaxSort*Sizeof(PhongSortRec));
  125.   FillChar(VectorObjects, Sizeof(VectorObjects), 0);
  126. End;
  127.  
  128. Procedure SelectEnable(Num, Ena : Byte; EnMap : Pointer);
  129.  
  130. Begin
  131.   VectorObjects[Num].Enabled := Ena;
  132.   VectorObjects[Num].EnvMap := EnMap;
  133. End;
  134.  
  135. Procedure FreeVectorObject(Num : Byte);
  136.  
  137. Begin
  138.   With VectorObjects[Num] do
  139.     Begin
  140.       Freemem(LocalVert, NumVert*Sizeof(LCoord));
  141.       Freemem(WorldVert, NumVert*Sizeof(LCoord));
  142.       Freemem(VertNorms, NumVert*Sizeof(LCoord));
  143.       Freemem(ScreenVert, NumVert*Sizeof(SCoord));
  144.       Freemem(RotateList, NumFacet*Sizeof(Byte));
  145.       Freemem(Normals,   NumFacet*Sizeof(LCoord));
  146.       Freemem(Polygons,  NumFacet*Sizeof(PolygonDef));
  147.     End;
  148. End;
  149.  
  150. {$F+}
  151. {$L Mat.OBJ}
  152. Procedure InitRotationMatrix(x, y, z : Integer); External;
  153. Procedure Rotate(Var Local, World, Screen, Mask; Num : Word; X, Y, Z : Longint); External;
  154. Procedure SingleRotate(Var Vertex; X, Y, Z : Word); External;
  155.  
  156. {$L ByteSort.Obj}
  157. Procedure ByteSort(Var PolyList; Num : Word; Var List : PByteList); External;
  158.  
  159. {$L Dot.Obj}
  160. Function DotProduct(Var V1, V2) : Longint; External;
  161. {$F-}
  162.  
  163.  
  164. Procedure LoadVectorObject(Data : Pointer; NumVecObjects, Shading : Byte);
  165.  
  166. Var
  167.   VecSeg, VecOfs : Word;
  168.   Temp : Integer;
  169.   Count : Integer;
  170.  
  171. Begin
  172.   VecSeg := Seg(Data^);
  173.   VecOfs := Ofs(Data^);
  174.   Temp := MemW[VecSeg:VecOfs];  { Read Flag }
  175.   Inc(VecOfs, 2);
  176.   VectorObjects[NumVecObjects].NumVert := MemW[VecSeg:VecOfs];
  177.   Inc(VecOfs, 2);
  178.   With VectorObjects[NumVecObjects] do
  179.     Begin
  180.       Getmem(LocalVert, NumVert*Sizeof(LCoord));
  181.       Getmem(WorldVert, NumVert*Sizeof(LCoord));
  182.       Getmem(VertNorms, NumVert*Sizeof(LCoord));
  183.       Getmem(ScreenVert, NumVert*Sizeof(SCoord));
  184.     End;
  185.   For Count := 0 to (VectorObjects[NumVecObjects].Numvert-1) do
  186.     Begin
  187.       Temp := MemW[VecSeg:VecOfs];
  188.       Inc(VecOfs, 2);
  189.       VectorObjects[NumVecObjects].LocalVert^[Count].x := Temp;
  190.       Temp := MemW[VecSeg:VecOfs];
  191.       Inc(VecOfs, 2);
  192.       VectorObjects[NumVecObjects].LocalVert^[Count].y := Temp;
  193.       Temp := MemW[VecSeg:VecOfs];
  194.       Inc(VecOfs, 2);
  195.       VectorObjects[NumVecObjects].LocalVert^[Count].z := Temp;
  196.     End;
  197.   VectorObjects[NumVecObjects].NumFacet := MemW[VecSeg:VecOfs];
  198.   Inc(VecOfs, 3);  { Read numpolys, and vif }
  199.   With VectorObjects[NumVecObjects] do
  200.     Begin
  201.       Getmem(Polygons, NumFacet*Sizeof(PolygonDef));
  202.       Getmem(Normals, NumFacet*Sizeof(LCoord));
  203.       Getmem(RotateList, NumFacet*Sizeof(Byte));
  204.     End;
  205.   For Count := 0 to (VectorObjects[NumVecObjects].NumFacet-1) do
  206.     Begin
  207.       Temp := MemW[VecSeg:VecOfs];
  208.       Inc(VecOfs, 2);
  209.       VectorObjects[NumVecObjects].Polygons^[Count].p1 := Temp;
  210.       Temp := MemW[VecSeg:VecOfs];
  211.       Inc(VecOfs, 2);
  212.       VectorObjects[NumVecObjects].Polygons^[Count].p2 := Temp;
  213.       Temp := MemW[VecSeg:VecOfs];
  214.       Inc(VecOfs, 2);
  215.       VectorObjects[NumVecObjects].Polygons^[Count].p3 := Temp;
  216.     End;
  217.   For Count := 0 to (VectorObjects[NumVecObjects].NumFacet-1) do
  218.     Begin
  219.       Temp := MemW[VecSeg:VecOfs];
  220.       Inc(VecOfs, 2);
  221.       VectorObjects[NumVecObjects].Normals^[Count].x := Temp*2;
  222.       Temp := MemW[VecSeg:VecOfs];
  223.       Inc(VecOfs, 2);
  224.       VectorObjects[NumVecObjects].Normals^[Count].y := Temp*2;
  225.       Temp := MemW[VecSeg:VecOfs];
  226.       Inc(VecOfs, 2);
  227.       VectorObjects[NumVecObjects].Normals^[Count].z := Temp*2;
  228.     End;
  229.   For Count := 0 to (VectorObjects[NumVecObjects].Numvert-1) do
  230.     Begin
  231.       Temp := MemW[VecSeg:VecOfs];
  232.       Inc(VecOfs, 2);
  233.       VectorObjects[NumVecObjects].VertNorms^[Count].x := Temp*2;
  234.       Temp := MemW[VecSeg:VecOfs];
  235.       Inc(VecOfs, 2);
  236.       VectorObjects[NumVecObjects].VertNorms^[Count].y := Temp*2;
  237.       Temp := MemW[VecSeg:VecOfs];
  238.       Inc(VecOfs, 2);
  239.       VectorObjects[NumVecObjects].VertNorms^[Count].z := Temp*2;
  240.     End;
  241.   VectorObjects[NumVecObjects].ShadeType := Shading;
  242. End;
  243.  
  244. Procedure CreateRotateList(Var SortCount : Integer; NumUse : Integer);
  245. { Creates the vertex mask table and the sort list }
  246. { Returns the number of polygons in the sort list }
  247.  
  248. Var
  249.   Count : Integer;
  250.   Dot : Longint;
  251.   SortStart : Integer;
  252.  
  253. Begin
  254.   SortStart := SortCount;
  255.   With VectorObjects[NumUse] do
  256.     Begin
  257.       For Count := 0 to (NumFacet-1) do
  258.         Begin
  259.           Dot := DotProduct(ObjectViewer, Normals^[Count]);
  260.           If Dot >= 0
  261.             Then Begin
  262.               With SortList^[SortCount] do
  263.                 Begin
  264.                   Index := Count;
  265.                   Next := Nil;
  266.                   OwnerIndex := NumUse;
  267.                   PolyType := ShadeType;
  268.  
  269.                 End;
  270.               RotateList^[Polygons^[Count].p1] := 1;
  271.               RotateList^[Polygons^[Count].p2] := 1;
  272.               RotateList^[Polygons^[Count].p3] := 1;
  273.               SortCount := SortCount + 1;
  274.             End;
  275.         End;
  276.       For Count := 0 to (NumVert - 1) do
  277.         Begin
  278.           If RotateList^[Count] = 1
  279.             Then Begin
  280.               DotList[Count].Viewer := DotProduct(ObjectViewer, VertNorms^[Count]);
  281.               DotList[Count].XAxis := DotProduct(XAxis, VertNorms^[Count]);
  282.               DotList[Count].YAxis := DotProduct(YAxis, VertNorms^[Count]);
  283.             End;
  284.          End;
  285.       If ShadeType = cGouraudPoly
  286.         Then Begin
  287.           For Count := SortStart to (SortCount-1) do
  288.             Begin
  289.               With GouraudSortRec(SortList^[Count]) do
  290.                 Begin
  291.                   If DotList[Polygons^[Index].p1].Viewer > 0
  292.                     Then C1 := Word(DotList[Polygons^[Index].p1].Viewer)*63 Shr 9
  293.                     Else C1 := 0;
  294.                   If DotList[Polygons^[Index].p2].Viewer > 0
  295.                     Then C2 := Word(DotList[Polygons^[Index].p2].Viewer)*63 Shr 9
  296.                     Else C2 := 0;
  297.                   If DotList[Polygons^[Index].p3].Viewer > 0
  298.                     Then C3 := Word(DotList[Polygons^[Index].p3].Viewer)*63 Shr 9
  299.                     Else C3 := 0;
  300.                   Base := 64*(SortList^[Count].Index And 1);
  301.                 End;
  302.             End;
  303.         End
  304.         Else Begin
  305.           For Count := SortStart to (SortCount-1) do
  306.             Begin
  307.               With SortList^[Count] do
  308.                 Begin
  309.                   Theta1 := 128 + Integer(DotList[Polygons^[Index].p1].XAxis) Shr 2;
  310.                   Phi1 :=   128 + Integer(DotList[Polygons^[Index].p1].YAxis) Shr 2;
  311.                   Theta2 := 128 + Integer(DotList[Polygons^[Index].p2].XAxis) Shr 2;
  312.                   Phi2 :=   128 + Integer(DotList[Polygons^[Index].p2].YAxis) Shr 2;
  313.                   Theta3 := 128 + Integer(DotList[Polygons^[Index].p3].XAxis) Shr 2;
  314.                   Phi3 :=   128 + Integer(DotList[Polygons^[Index].p3].YAxis) Shr 2;
  315.                 End;
  316.             End;
  317.         End;
  318.   End;
  319. End;
  320.  
  321. Procedure GetZMidValues(Num : Integer);
  322.  
  323. Var
  324.   Count : Integer;
  325.   T1, T2, T3 : Integer;
  326.  
  327. Begin
  328.   For Count := 0 to (Num-1) do
  329.     Begin
  330.       T1 := VectorObjects[SortList^[Count].OwnerIndex].Polygons^[SortList^[Count].Index].p1;
  331.       T2 := VectorObjects[SortList^[Count].OwnerIndex].Polygons^[SortList^[Count].Index].p2;
  332.       T3 := VectorObjects[SortList^[Count].OwnerIndex].Polygons^[SortList^[Count].Index].p3;
  333.       SortList^[Count].ZMid :=
  334.         Word(VectorObjects[SortList^[Count].OwnerIndex].WorldVert^[T1].z +
  335.              VectorObjects[SortList^[Count].OwnerIndex].WorldVert^[T2].z +
  336.              VectorObjects[SortList^[Count].OwnerIndex].WorldVert^[T3].z)
  337.             Div 3;
  338.     End;
  339. End;
  340.  
  341. Procedure DisplayPolygons(PgSeg : Word);
  342.  
  343. Var
  344.   Radix : Word;
  345.   OI : Integer;
  346.   T1, T2, T3 : Integer;
  347.  
  348. Begin
  349.   For Radix := 255 downto 0 do
  350.     While MSBList^[Radix] <> Nil do
  351.       Begin
  352.         OI := MSBList^[Radix]^.OwnerIndex;
  353.         T1 := VectorObjects[OI].Polygons^[MSBList^[Radix]^.Index].p1;
  354.         T2 := VectorObjects[OI].Polygons^[MSBList^[Radix]^.Index].p2;
  355.         T3 := VectorObjects[OI].Polygons^[MSBList^[Radix]^.Index].p3;
  356.         If MSBList^[Radix]^.PolyType = cGouraudPoly
  357.           Then Begin
  358.             GouraudClipPolygon(VectorObjects[OI].ScreenVert^[T1].x, VectorObjects[OI].ScreenVert^[T1].y,
  359.                                VectorObjects[OI].ScreenVert^[T2].x, VectorObjects[OI].ScreenVert^[T2].y,
  360.                                VectorObjects[OI].ScreenVert^[T3].x, VectorObjects[OI].ScreenVert^[T3].y,
  361.                                GouraudSortRec(MSBList^[Radix]^).Base+GouraudSortRec(MSBList^[Radix]^).C1,
  362.                                GouraudSortRec(MSBList^[Radix]^).Base+GouraudSortRec(MSBList^[Radix]^).C2,
  363.                                GouraudSortRec(MSBList^[Radix]^).Base+GouraudSortRec(MSBList^[Radix]^).C3,
  364.                                PgSeg);
  365.           End
  366.           Else Begin
  367.             PhongClipPolygon(VectorObjects[OI].ScreenVert^[T1].x, VectorObjects[OI].ScreenVert^[T1].y,
  368.                              VectorObjects[OI].ScreenVert^[T2].x, VectorObjects[OI].ScreenVert^[T2].y,
  369.                              VectorObjects[OI].ScreenVert^[T3].x, VectorObjects[OI].ScreenVert^[T3].y,
  370.                              (MSBList^[Radix]^).Theta1, (MSBList^[Radix]^).Phi1,
  371.                              (MSBList^[Radix]^).Theta2, (MSBList^[Radix]^).Phi2,
  372.                              (MSBList^[Radix]^).Theta3, (MSBList^[Radix]^).Phi3,
  373.                              PgSeg, VectorObjects[OI].EnvMap);
  374.           End;
  375.         MSBList^[Radix] := MSBList^[Radix]^.Next;
  376.       End;
  377. End;
  378.  
  379. Procedure DisplayVectorObjects(VPage : Word);
  380. { Displays all Vector Objects with the enabled bit on }
  381.  
  382. Var
  383.   Count : Integer;
  384.   SortCount : Integer;
  385.  
  386. Begin
  387.   SortCount := 0;
  388.   For Count := 0 to 3 do
  389.     Begin
  390.       If VectorObjects[Count].Enabled = 1
  391.         Then Begin
  392.           With VectorObjects[Count] do
  393.             Begin
  394.               ObjectViewer.x := 0; ObjectViewer.y := 0; ObjectViewer.z := -512;
  395.               XAxis.x := -512;      XAxis.y := 0;        XAxis.z := 0;
  396.               YAxis.x := 0;        YAxis.y := -512;      YAxis.z := 0;
  397.               SingleRotate(ObjectViewer, (511-xa), (511-ya), (511-za));
  398.               SingleRotate(XAxis, (511-xa), (511-ya), (511-za));
  399.               SingleRotate(YAxis, (511-xa), (511-ya), (511-za));
  400.               CreateRotateList(SortCount, Count);
  401.               InitRotationMatrix(xa, ya, za);
  402.               Rotate(LocalVert^, WorldVert^, ScreenVert^, RotateList^, NumVert, xt, yt, zt);
  403.            End;
  404.       End;
  405.     End;
  406.   GetZMidValues(SortCount);
  407.   ByteSort(SortList^, SortCount, MSBList);
  408.   DisplayPolygons(VPage);
  409. End;
  410.  
  411. Begin
  412. End.