All pastes #2132259 Raw Edit

vip3d.pas

public text v1 · immutable
#2132259 ·published 2012-03-26 16:43 UTC
rendered paste body
{$I maindef.pas}

unit vip3d;
interface
uses io,tools,vipgfx,math3d;

const
      maxArr=400;
      z_max=-1000;
      xscale=640;
      yscale=480;
      {
       shiftconst=8; for 320x200
       shiftconst=9; for 640x480
      }
      shiftconst=9;
var clear_translation:Longint=0;
    FOCALDISTANCE : single = 256;

var Zbuffer : dword;
    zAddValue : Longint;

type
        tV3Dvertex=record
                    x,y,z:single;
                    nx,ny,nz:single;
                    u,v:single;
                    r,g,b,a:byte;
                   end;


        tV3Dpoly=record
                  A,B,C:tV3Dvertex;

                  nx,ny,nz:single;
                  matNum:dword;
                 end;

        tV3Dobject=record
                    posX,posY,posZ:single;

                    numPolys:dword;
                    Poly: array [0..maxArr] of tV3dpoly;

                   end;







procedure ClearZBuffer;


Procedure SwapB(Var A : byte;    Var B : byte);
Procedure SwapL(Var A : Longint; Var B : Longint);
Procedure SwapD(Var A : dword; Var B : dword);
Procedure SwapS(Var A : Single;  Var B : Single);
Procedure SwapV(var a : tV3DVertex; var b : tV3Dvertex);



function CreateV3DVertex(x,y,z,nx,ny,nz,u,v:single;r,g,b,a:byte):tV3DVertex;

Function CreateV3DPoly(A,B,C:tV3Dvertex;nx,ny,nz:single;matNum:dword):tV3Dpoly;





procedure AddPoly(thePoly:tV3Dpoly;var theObject:tV3Dobject);
function  ExtractPoly(theObject:tV3Dobject;polyNum:dword):tV3Dpoly;
procedure PackPoly(var theObject:tV3Dobject;thePoly:tV3Dpoly;polynum:dword);



procedure RenderObject(theObject:tV3Dobject);



procedure MoveObject(var theObject:tV3Dobject; x,y,z:single);
procedure RotateObject(var theObject:tV3Dobject; x,y,z:single);


procedure move_Vertex(var Vrtx:tV3DVertex;MoveX,MoveY,MoveZ:Single);
function  Rotate_Vertex(var Vctr:tV3DVertex;CenterX,CenterY,CenterZ,AngleX,AngleY,AngleZ:Single):tV3DVertex; {Angle=0..360}

function  Rotate_Vertex_X(vctr:tV3DVertex;angle:single):tV3Dvertex;
function  Rotate_Vertex_Y(vctr:tV3Dvertex;angle:single):tV3Dvertex;
function  Rotate_Vertex_Z(vctr:tV3Dvertex;angle:single):tV3Dvertex;





function TriangleBackface(vA,vB,vC:tV3DVertex):boolean;


procedure makeProjection(V:tV3Dvertex;var X,Y,Z:single);


{LOADERS\txttools.pas}
const
       obj_V:byte=1;
       obj_VT:byte=2;
       obj_VN:byte=3;
       obj_F:byte=4;
       obj_S:byte=5;

type obj_tVector3f=packed record
                x,y,z:single;
               end;
     obj_tVector2f=packed record
                u,v:single;
               end;
     obj_tFaceInfo=packed record
                    AvListNum:dword;
                    AtListNum:dword;
                    AnListNum:dword;
                    BvListNum:dword;
                    BtListNum:dword;
                    BnListNum:dword;
                    CvListNum:dword;
                    CtListNum:dword;
                    CnListNum:dword;
                    SmothingGroup:dword;
                   end;


function obj_GetFirstSign(s:String):byte;
function obj_GetVector3f(s:string):obj_tVector3f;
function obj_GetVector2f(s:string):obj_tVector2f;
function obj_GetFaceInfo(s:String):obj_tFaceInfo;
function obj_GetSmothingGroup(s:string):dword;


{LOADERS\objlib.pas}

procedure Load3DOBJ(filename:string;var theObject:tV3Dobject);



implementation
uses math;

{$I 3Dinc\loaders\txttools.pas}
{$I 3Dinc\loaders\objlib.pas}

{$I 3Dinc\shader\flat.inc}

procedure ClearZBuffer;
var x,y:dword;
begin
 for y:=0 to yscale-1 do
  for x:=0 to xscale-1 do begin
    //putL(Zbuffer+ ((y*xscale+x) shl 2),z_max shl 4);
     asm
       mov eax,y
      imul eax,xscale
       add eax,x
       shl eax,2
       add eax,zBuffer

       mov edx,z_max
       shl edx,4

       mov [eax],edx
     end;
    end;

end;


Procedure SwapB(Var A : byte; Var B : byte);
var t:byte;
Begin
    t:=A;
    a:=B;
    b:=t;
End;


Procedure SwapL(Var A : Longint; Var B : Longint);
var t:Longint;
Begin
    t:=A;
    a:=B;
    b:=t;
End;

Procedure SwapD(Var A : dword; Var B : dword);
var t:dword;
Begin
    t:=A;
    a:=B;
    b:=t;
End;


Procedure SwapS(Var A : Single; Var B : Single);
var t:Single;
Begin
    t:=A;
    a:=B;
    b:=t;
End;

Procedure SwapV(var a:tV3Dvertex; var b:tV3Dvertex);
var t:tV3Dvertex;
Begin
    t:=A;
    a:=B;
    b:=t;
End;


function TriangleBackface(vA,vB,vC:tV3Dvertex):boolean;
var
    x1,x2,x3:single;
    y1,y2,y3:single;
    z1,z2,z3:single;
    a,b,c,d:single;
begin

   x1:=vA.x;
   x2:=vB.x;
   x3:=vC.x;

   y1:=vA.y;
   y2:=vB.y;
   y3:=vC.y;

   z1:=vA.z;
   z2:=vB.z;
   z3:=vC.z;

   A:=y1*(z2-z3)+y2*(z3-z1)+y3*(z1-z2);
   B:=z1*(x2-x3)+z2*(x3-x1)+z3*(x1-x2);
   C:=x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2);
   D:=-x1*(y2*z3-y3*z2)-x2*(y3*z1-y1*z3)-x3*(y1*z2-y2*z1);

   if D<0 then trianglebackface:=true else trianglebackface:=false;

end;

procedure makeProjection(V:tV3Dvertex;var X,Y,Z:single);
begin
 z:=V.z;
 if z=0 then begin
     x:=0;
     y:=0;
     exit;
 end;
 x:=FOCALDISTANCE * V.x / z + xscale / 2 + 0.5;
 y:=FOCALDISTANCE * V.y / z  * -1 + yscale / 2 + 0.5;
end;


function CreateV3DVertex(x,y,z,nx,ny,nz,u,v:single;r,g,b,a:byte):tV3DVertex;
var myVertex:tV3DVertex;
begin

  myVertex.x:=x;
  myVertex.y:=y;
  myVertex.z:=z;
  myVertex.nx:=nx;
  myVertex.ny:=ny;
  myVertex.nz:=nz;
  myVertex.u:=u;
  myVertex.v:=v;
  myVertex.r:=r;
  myVertex.g:=g;
  myVertex.b:=b;
  myVertex.a:=a;

  CreateV3DVertex:=myVertex;
end;


Function CreateV3DPoly(A,B,C:tV3Dvertex;nx,ny,nz:single;matNum:dword):tV3Dpoly;
Var TempPoly : tV3Dpoly;
Begin
    TempPoly.A:=A;
    TempPoly.B:=B;
    TempPoly.C:=C;
    TempPoly.nx:=nx;
    TempPoly.ny:=ny;
    TempPoly.nz:=nz;
    TempPoly.matNum:=matNum;
    CreateV3DPoly:=TempPoly;
End;


procedure MoveObject(var theObject:tV3Dobject; x,y,z:single);
var i:dword;
    myPoly:tV3Dpoly;
    A,B,C:tV3Dvertex;
begin


 for i:=0 to theObject.numPolys-1 do begin

   myPoly:=extractPoly(theObject,i);
   A:=myPoly.A;
   move_Vertex(A,x,y,z);
   myPoly.A:=A;
   B:=myPoly.B;
   move_Vertex(B,x,y,z);
   myPoly.B:=B;
   C:=myPoly.C;
   move_Vertex(C,x,y,z);
   myPoly.C:=C;
   packPoly(theObject,myPoly,i);

 end;

end;


procedure RotateObject(var theObject:tV3Dobject; x,y,z:single);
var i:dword;
    myPoly:tV3Dpoly;
    A,B,C:tV3DVertex;
begin


 for i:=0 to theObject.numPolys-1 do begin


   myPoly:=extractPoly(theObject,i);

   A:=myPoly.A;
   myPoly.A:=rotate_Vertex_x(A,x);

   A:=myPoly.A;
   myPoly.A:=rotate_Vertex_y(A,y);

   A:=myPoly.A;
   myPoly.A:=rotate_Vertex_z(A,z);


   B:=myPoly.B;
   myPoly.B:=rotate_Vertex_x(B,x);

   B:=myPoly.B;
   myPoly.B:=rotate_Vertex_y(B,y);

   B:=myPoly.B;
   myPoly.B:=rotate_Vertex_z(B,z);


   C:=myPoly.C;
   myPoly.C:=rotate_Vertex_x(C,x);

   C:=myPoly.C;
   myPoly.C:=rotate_Vertex_y(C,y);

   C:=myPoly.C;
   myPoly.C:=rotate_Vertex_z(C,z);

   packPoly(theObject,myPoly,i);

 end;

end;

procedure RenderObject(theObject:tV3Dobject);
var i:longint;
    myPoly:tV3DPoly;
begin

 for i:=0 to theObject.numPolys-1 do begin
          lognum(i);
         myPoly:=theObject.Poly[i];
// if not TriangleBackface(myPoly.A,myPoly.B,myPoly.C) then
          Triangle(myPoly.A,myPoly.B,myPoly.C,vscreen);

 end;

end;





procedure AddPoly(thePoly:tV3DPoly;var theObject:tV3Dobject);
var p,pp,ppp:pointer;
    i,d,dd,ddd:dword;
    x:dword;
    myPoly:tV3DPoly;
Begin

//  getmem(theObject.polyEntriesList[theObject.numPolys],sizeof(tV3DPoly));

  myPoly:=thePoly;

         myPoly.A.r:=random(255);
         myPoly.A.g:=random(255);
         myPoly.A.b:=random(255);


//  move(myPoly,theObject.polyEntriesList[theObject.numPolys]^,sizeof(tV3DPoly));

  theObject.poly[theObject.numPolys]:=myPoly;

  inc(theObject.numPolys);

End;


procedure PackPoly(var theObject:tV3Dobject;thePoly:tV3Dpoly;polynum:dword);
begin

// move(thePoly,theObject.polyEntriesList[polynum]^,sizeof(tV3DPoly));

 theObject.poly[polynum]:=thePoly;

end;




function  ExtractPoly(theObject:tV3Dobject;polyNum:dword):tV3Dpoly;
var poly:tV3Dpoly;
begin
  poly:=theObject.poly[polynum];
  ExtractPoly:=poly;
end;

procedure  move_vertex(var Vrtx:tV3Dvertex;MoveX,MoveY,MoveZ:Single);
Begin
 Vrtx.X:=Vrtx.X+MoveX;
 Vrtx.Y:=Vrtx.Y+MoveY;
 Vrtx.Z:=Vrtx.Z+MoveZ;
End;


function  Rotate_Vertex(var Vctr:tV3Dvertex;CenterX,CenterY,CenterZ,AngleX,AngleY,AngleZ:Single):tV3Dvertex; {Angle=0..360}
Var  RadX,RadY,RadZ,
     SinX,SinY,SinZ,
     CosX,CosY,CosZ,
     TempX,TempY,TempZ,
     Holder      :Single;
     aVctr:tV3Dvertex;
Begin
    With Vctr do
    Begin

      TempX:=X-CenterX;
      TempY:=Y-CenterY;
      TempZ:=Z-CenterZ;

      RadX:=AngleX*Theta;
      RadY:=AngleY*Theta;
      RadZ:=AngleZ*Theta;

      SinX:=Sin (RadX);
      CosX:=Cos (RadX);

      SinY:=Sin (RadY);
      CosY:=Cos (RadY);

      SinZ:=Sin (RadZ);
      CosZ:=Cos (RadZ);


      Holder := TempY * CosY  -  TempZ * SinX;
      TempZ  := TempY * SinX  +  TempZ * CosX;
      TempY  := Holder;

      Holder := TempX * CosY  -  TempZ * SinY;
      TempZ  := TempX * SinY  +  TempZ * CosY;
      TempX  := Holder;

      Holder := TempX * CosZ  -  TempY * SinZ;
      TempY  := TempX * SinZ  +  TempY * CosZ;
      TempX  := Holder;

      aVctr.X:=TempX+CenterX;
      aVctr.Y:=TempY+CenterY;
      aVctr.Z:=TempZ+CenterZ;
    End;
 Rotate_Vertex:=aVctr;
End;

function Rotate_Vertex_X(vctr:tV3Dvertex;angle:single):tV3Dvertex;
var v:tV3Dvertex;
begin
 v:=vctr;
 v.x:=vctr.x;
 v.y:=cos(angle)*vctr.y - Sin(angle)*vctr.z;
 v.z:=sin(angle)*vctr.y + Cos(angle)*vctr.z;
 rotate_Vertex_X:=v;
end;

function Rotate_Vertex_Y(vctr:tV3Dvertex;angle:single):tV3Dvertex;
var v:tV3Dvertex;
begin
 v:=vctr;
 v.x:=cos(angle)*vctr.x - Sin(angle)*vctr.z;
 v.y:=vctr.y;
 v.z:=sin(angle)*vctr.x + Cos(angle)*vctr.z;
 rotate_vertex_y:=v;
end;

function Rotate_Vertex_Z(vctr:tV3Dvertex;angle:single):tV3Dvertex;
var v:tV3Dvertex;
begin
 v:=vctr;
 v.x:=cos(angle)*vctr.x - Sin(angle)*vctr.y;
 v.y:=sin(angle)*vctr.x + Cos(angle)*vctr.y;
 v.z:=vctr.z;
 rotate_Vertex_Z:=v;
end;

begin

end.