[Back to EGAVGA SWAG index]  [Back to Main SWAG index]  [Original]

{
OK here is a texture mapped vector cube. Sorry the code is so squashed, but
I wanted to keep it to 2 messages. This code took me about a day to crank out
so it isn't too optimized.
}

Program TextureVector;
{ Alex Chalfin  10/15/94          }
{ Internet: achalfin@uceng.uc.edu }
{ Fidonet: 1:108/180              }
{$G+}

Type LongCoord=Record x,y,z:Longint; End; SCoord=Record x,y:Integer;End;
  VCoords=Array[0..7] of LongCoord; NCoords=Array[0..5] of LongCoord;
  SinglePoly=Array[0..3] of Byte; PLT=Array[0..5] of SinglePoly;
  SideValues=Record X:Integer;Px,Py:Byte;End;
  SideTable=Array[0..199] of SideValues;

Const
  LocalCoords:VCoords=((x:50;y:50;z:50),(x:50;y:-50;z:50),(x:-50;y:-50;z:50),
  (x:-50;y:50;z:50),(x:50;y:50;z:-50),(x:50;y:-50;z:-50),(x:-50;y:-50;z:-50),
  (x:-50; y:50; z:-50));
  LocalNorms:NCoords=((x:0;y:0;z:256),(x:0;y:0;z:-256),(x:0;y:-256;z:0),
             (x:-256;y:0;z:0),(x:0;y:256;z:0),(x:256;y:0;z:0));
  Poly:PLT=((0,3,2,1),(5,6,7,4),(1,2,6,5),(2,3,7,6),(3,0,4,7),(0,1,5,4));
  Top=1;Bottom=2;Left=3;Right=4;MapShift=5;PicW=32;

Var Page1,Page0:Pointer; Sine,CoSine:Array[0..511] of Longint;
  LookUp:Array[0..199] of Word; WorldCoords:VCoords; WorldNorms:NCoords;
  SC : Array[0..7] of SCoord; Xa, Ya, Za : Word;
  LeftTable, RightTable : SideTable;

Const BitMap : Array[0..PicW*PicW-1] of Byte = (
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,5,5,5,2,2,5,5,5,5,2,2,2,2,2,2,2,2,2,5,5,5,2,2,
2,2,2,2,5,5,5,1,1,5,5,2,5,5,2,5,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,2,5,
5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,2,5,5,1,1,5,2,5,
5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,2,5,5,1,1,5,2,5,5,5,5,2,5,5,
2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,
5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,
5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,
5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,
2,5,5,5,5,2,5,5,2,2,2,2,2,2,2,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,2,2,2,2,2,
5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,
5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,
5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,
5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,
1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,
5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,
5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,
5,5,5,2,5,5,5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,
5,5,5,5,5,5,5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,5,5,
5,1,1,5,2,5,5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,2,5,5,1,1,5,2,5,
5,5,5,2,5,5,2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,2,5,5,1,1,5,2,5,5,5,5,2,5,5,
2,5,5,5,5,5,5,5,5,5,5,2,5,5,5,5,5,5,2,5,5,1,1,5,2,5,5,5,5,2,5,5,2,2,2,2,2,2,
2,2,2,5,5,5,2,2,2,2,2,2,5,5,5,1,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,1,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);

Procedure ScanLeft(X1, Y1, X2, Y2, Edge : Integer);
Var Count,XVal,XAdd : Integer; Px, Py : Byte; PxConst : Boolean;

Begin;XVal := (X1) Shl 8;XAdd := ((X2-X1) Shl 8) Div (Y2-Y1+1);
  For Count := Y1 to Y2 do Begin
   LeftTable[Count].X:=XVal Shr 8;XVal:=XVal+XAdd; End;
  If Edge = Top Then Begin;X1:=PicW-1;X2:=0;Py:=0;PxConst:=False;End;
  If Edge = Right Then Begin;X1:=PicW-1;X2:=0;Px:=PicW-1;PxConst:=True;End;
  If Edge = Bottom Then Begin;X1:=0;X2:=PicW-1;Py:=PicW-1;PxConst:=False;End;
  If Edge = Left Then Begin;X1:=0;X2:=PicW-1;Px:=0;PxConst:=True;End;
  If PxConst Then Begin
      XVal := X1 Shl 8;XAdd := ((X2-X1) Shl 8) Div (Y2-Y1+1);
      For Count := Y1 to Y2 do Begin
          LeftTable[Count].Px := Px;LeftTable[Count].Py := XVal Shr 8;
          XVal := XVal + XAdd;End;End
    Else Begin XVal := X1 Shl 8;XAdd := ((X2-X1) Shl 8) Div (Y2-Y1+1);
      For Count := Y1 to Y2 do  Begin
          LeftTable[Count].Px := XVal Shr 8;LeftTable[Count].Py := Py;
          XVal := XVal + XAdd;End;End;
End;


Procedure ScanRight(X1, Y1, X2, Y2, Edge : Integer);
Var Count,XVal,XAdd : Integer;Px, Py : Byte;PxConst : Boolean;
Begin
  XVal := X1 Shl 8;XAdd := ((X2-X1) Shl 8) Div (Y2-Y1+1);
  For Count := Y1 to Y2 do Begin RightTable[Count].X:=XVal Shr 8;
    XVal:=XVal+XAdd;End;
 If Edge = Top Then Begin X1 := 0;X2 := PicW-1;Py := 0;PxConst := False;End;
 If Edge = Right Then Begin X1:=0;X2:=PicW-1;Px:=PicW-1;PxConst:=True;End;
 If Edge = Bottom Then Begin X1:=PicW-1;X2:=0;Py:=PicW-1;PxConst:=False;End;
 If Edge = Left Then Begin X1:=PicW-1;X2:=0;Px:=0;PxConst := True; End;
 If PxConst Then Begin XVal:=X1 Shl 8;XAdd:=((X2-X1) Shl 8) Div (Y2-Y1+1);
      For Count := Y1 to Y2+1 do Begin
          RightTable[Count].Px := Px; RightTable[Count].Py := XVal Shr 8;
          XVal := XVal + XAdd; End;End
    Else Begin XVal := X1 Shl 8;XAdd := ((X2-X1) Shl 8) Div (Y2-Y1+1);
      For Count := Y1 to Y2 do Begin RightTable[Count].Px := XVal Shr 8;
          RightTable[Count].Py := Py; XVal := XVal + XAdd;End;End;End;

Procedure Swap(Var a,b : Integer);
Var t : Integer; Begin t := a;a := b;b := t; End;

Procedure ScanConvert(X1, Y1, X2, Y2, Edge : Integer);
Begin If Y2 < Y1 Then Begin Swap(X1, X2);Swap(Y1, Y2);
  ScanLeft(X1,Y1,X2,Y2,Edge); End Else ScanRight(X1,Y1,X2,Y2,Edge); End;

Procedure DisplayTexture(Min, Max : Integer);
Var P1,P2,YCount,XCount,XVal,XAdd,YVal,YAdd : Integer; Offset1 : Word;
Begin For YCount := Min to Max do Begin
 YVal := LeftTable[YCount].Py Shl 8; XVal := LeftTable[YCount].Px Shl 8;
 P1 := LeftTable[YCount].X; P2 := RightTable[YCount].X;
 If P2 < P1 Then Swap(P2,P1);
 XAdd := ((RightTable[YCount].Px-LeftTable[YCount].Px) Shl 8) Div (P2-P1+1);
 YAdd := ((RightTable[YCount].Py-LeftTable[YCount].Py) Shl 8) Div (P2-P1+1);
 Offset1 := LookUp[YCount]+P1+Ofs(Page1^);
 For XCount := P1 to P2 do Begin
   Mem[Seg(Page1^):Offset1]:=BitMap[(XVal Shr 8)+(YVal Shr 8) Shl MapShift];
   XVal:=XVal+XAdd;YVal := YVal+YAdd; Offset1 := Offset1 + 1;End;End;End;

Procedure TextureMap(X1, Y1, X2, Y2, X3, Y3, X4, Y4 : Integer);
Var Count,MinY,MaxY : Integer;
Begin MinY := Y1;MaxY := Y1;
  If Y2 > MaxY Then MaxY := Y2;If Y3 > MaxY Then MaxY := Y3;
  If Y4 > MaxY Then MaxY := Y4;If Y2 < MinY Then MinY := Y2;
  If Y3 < MinY Then MinY := Y3;If Y4 < MinY Then MinY := Y4;
  ScanConvert(X1, Y1, X2, Y2, Top);ScanConvert(X2, Y2, X3, Y3, Right);
  ScanConvert(X3, Y3, X4, Y4, Bottom);ScanConvert(X4, Y4, X1, Y1, Left);
  DisplayTexture(MinY, MaxY);End;

Procedure CalcSinus;
Var C : Longint;
Begin For C := 0 to 511 do Begin
Sine[C]:=Round(Sin(C*(2*Pi)/512)*2048);
CoSine[C]:=Round(Cos(C*(2*Pi)/512)*2048); End;
For c := 0 to 199 do LookUp[c] := c*320; End;

Function SAR(S, B : Longint) : Longint;
Begin If S<0 Then SAR:=-((-S) Shr B) Else SAR:=(S Shr B); End;

Procedure Rotate3D(Var Loc, Wor; Num, Xa, Ya, Za : Word);
Var Local:NCoords Absolute Loc;World:NCoords Absolute Wor;
x,y,z,Xt,Yt,Zt,C : Longint;
Begin For C := 0 to (Num-1) do Begin
  x:=Local[C].x;y:=Local[C].y;z:=Local[C].z;
  Yt:=Sar(Y*CoSine[Xa]-Z*Sine[Xa],11);Zt:=Sar(Y*Sine[Xa]+Z*CoSine[Xa],11);
  Y:=Yt;Z:=Zt;Xt:=Sar(X*CoSine[Ya]-Z*Sine[Ya],11);
  Zt:=Sar(X*Sine[Ya]+Z*CoSine[Ya],11);X:=Xt;Z:=Zt;
  Xt:=Sar(X*CoSine[Za]-Y*Sine[Za],11);Yt:=Sar(X*Sine[Za]+Y*CoSine[Za],11);
  X:=Xt;Y:=Yt;World[C].x:=X;World[C].y:=Y;World[C].z:=Z;End; End;

Procedure DrawPolygons;
Var c : Integer; Dot : Longint;
Begin For c:=0 to 7 do With WorldCoords[c] do Begin
 SC[c].x:=(x Shl 9)Div(512-z)+160; SC[c].y:=(y Shl 9)Div(512-z)+100; End;
 For c := 0 to 5 do Begin Dot:=WorldNorms[c].z Shl 11; If Dot>=0
  Then TextureMap(SC[Poly[c,0]].x,SC[Poly[c,0]].y,
  SC[Poly[c,1]].x,SC[Poly[c,1]].y,SC[Poly[c,2]].x,SC[Poly[c,2]].y,
  SC[Poly[c,3]].x,SC[Poly[c,3]].y); End; End;

Procedure CopyPage(Var S, D); Assembler;
Asm;Push ds;Lds si,S;Les di,d;Mov cx,32000;Rep Movsw;Pop ds;End;

Procedure ClearPage(Var S); Assembler;
Asm; Les  di,S;Mov  ax,0;Mov  cx,32000;Rep  Stosw;End;

Begin
  Asm;Mov ax,13h;Int 10h;End;GetMem(Page1,65530);Page0:=Ptr($A000,0);
  ClearPage(Page1^);Xa:=0;Ya:=0;Za:=0; CalcSinus; Repeat
  Rotate3d(LocalCoords,WorldCoords,8,Xa,Ya,Za);
  Rotate3d(LocalNorms,WorldNorms,6,Xa,Ya,Za);DrawPolygons;
  CopyPage(Page1^,Page0^); ClearPage(Page1^);Xa:=(Xa+6) And 511;
  Ya:=(Ya+3) And 511;Za:=(Za+4) And 511; Until Port[$60]=1;
  Freemem(Page1, 65535); Asm; Mov ax,3; Int 10h; End;
End.


[Back to EGAVGA SWAG index]  [Back to Main SWAG index]  [Original]