{ 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.