{$MODE OBJFPC}
uses tools,vipgfx,vis,math;
const
v3dMaxVertex=8;
type
v3dVector = record
x,y,z,w:single;
end;
v3dPoly = record
v:array [0..v3dMaxVertex] of v3dVector;
numVertex:dword;
n:v3dVector;
matNum:dword;
end;
v3dObject = record
name:string;
center:v3dVector;
scale:single;
position,rotation:v3dVector;
polys:array of v3dPoly;
translatedPolys:array of v3dPoly;
numPolys:dword;
end;
function aVector(x,y,z:single):v3dVector;
var v:v3dVector;
begin
v.x:=X;
v.Y:=Y;
v.z:=Z;
v.w:=1;
aVector:=v;
end;
procedure v3dRasterizeWire(poly:v3dPoly; color:dword);
var i,ii:longint;
x1,y1,x2,y2:longint;
begin
ii:=0;
for i:=0 to poly.numVertex-1 do begin
inc(ii);
if ii>=poly.numVertex then ii:=0;
x1:=ceil(poly.v[i].x);
y1:=ceil(poly.v[i].y);
x2:=ceil(poly.v[ii].x);
y2:=ceil(poly.v[ii].y);
drawline(vscreen,x1,y1,x2,y2,color);
end;
end;
function v3dCreatePoly(v1,v2,v3:v3dVector):v3dPoly;
var i:dword;
p:v3dPoly;
begin
p.numVertex:=3;
p.v[0]:=v1;
p.v[1]:=v2;
p.v[2]:=v3;
v3dCreatePoly:=p;
end;
function v3dCreateObject(name:string; x,y,z:single):v3dObject;
var o:v3dObject;
begin
o.name:=name;
setLength(o.polys,0);
setLength(o.translatedPolys,0);
o.numPolys:=0;
o.center:=aVector(x,y,z);
o.position:=aVector(0,0,0);
o.rotation:=aVector(0,0,0);
o.scale:=1;
v3dCreateObject:=o;
end;
procedure v3dAddPolyToObject(var o:v3dObject; p:v3dPoly);
begin
inc(o.numPolys);
setLength(o.polys,o.numPolys);
setLength(o.translatedPolys,o.numPolys);
o.polys[o.numPolys-1]:=p;
end;
const
width=512;
height=512;
fullscreen=false;
var
theObject:v3dObject;
operator + (a,b:v3dVector):v3dVector;
begin
result.x:=a.x + b.x;
result.y:=a.y + b.y;
result.z:=a.z + b.z;
result.w:=1;
end;
function v3dMakeProjection(v:v3dVector):v3dVector;
var outV:v3dVector;
centerX,centerY:longint;
begin
outV:=v;
centerX:=vscreen.width div 2;
centerY:=vscreen.height div 2;
outV.x:=v.x / v.z * 256 + centerX;
outV.y:=v.y / v.z * -1 * 256 + centerY;
v3dMakeProjection:=outV;
end;
procedure v3dRenderPoly(poly:v3dPoly);
var
i:dword;
p:v3dPoly;
begin
for i:=0 to poly.numVertex-1 do p.v[i]:=v3dMakeProjection(poly.v[i]);
p.numVertex:=poly.numVertex;
v3dRasterizeWire(p,$ffffffff);
end;
procedure v3dRenderObject(var o:v3dObject);
var i,ii:dword;
begin
for i:=0 to o.numPolys-1 do begin
o.translatedPolys[i].numVertex:=o.polys[i].numVertex;
for ii:=0 to o.polys[i].numVertex-1 do o.translatedPolys[i].v[ii]:=o.Polys[i].v[ii] + o.position;
v3dRenderPoly(o.translatedPolys[i]);
end;
end;
const
speed=0.01;
var
rx:single=0;
ry:single=0;
rz:single=0;
r:single=0;
mx:single=0;
my:single=0;
mz:single=2;
procedure move;
begin
if KEYBOARD[KEY_T] then begin
mz:=mz-speed;
end;
if KEYBOARD[KEY_G] then begin
mz:=mz+speed;
end;
if KEYBOARD[KEY_UP] then begin
my:=my-speed;
end;
if KEYBOARD[KEY_DOWN] then begin
my:=my+speed;
end;
if KEYBOARD[KEY_LEFT] then begin
mx:=mx-speed;
end;
if KEYBOARD[KEY_RIGHT] then begin
mx:=mx+speed;
end;
theObject.position:=aVector(mx,my,mz);
end;
function cube:v3dObject;
var
v1,v2,v3:v3dVector;
p:v3dPoly;
o:v3dObject;
begin
o:=v3dCreateObject('box',0,0,0);
v1:=aVector(-1.0,-1.0,-1.0);
v2:=aVector(-1.0,-1.0, 1.0);
v3:=aVector(-1.0, 1.0, 1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0, 1.0,-1.0);
v2:=aVector(-1.0,-1.0,-1.0);
v3:=aVector(-1.0, 1.0,-1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0,-1.0, 1.0);
v2:=aVector(-1.0,-1.0,-1.0);
v3:=aVector(1.0,-1.0,-1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0, 1.0,-1.0);
v2:=aVector(1.0,-1.0,-1.0);
v3:=aVector(-1.0,-1.0,-1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(-1.0,-1.0,-1.0);
v2:=aVector(-1.0, 1.0, 1.0);
v3:=aVector(-1.0, 1.0,-1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0,-1.0, 1.0);
v2:=aVector(-1.0,-1.0, 1.0);
v3:=aVector(-1.0,-1.0,-1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(-1.0, 1.0, 1.0);
v2:=aVector(-1.0,-1.0, 1.0);
v3:=aVector(1.0,-1.0, 1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0, 1.0, 1.0);
v2:=aVector(1.0,-1.0,-1.0);
v3:=aVector(1.0, 1.0,-1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0,-1.0,-1.0);
v2:=aVector(1.0, 1.0, 1.0);
v3:=aVector(1.0,-1.0, 1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0, 1.0, 1.0);
v2:=aVector(1.0, 1.0,-1.0);
v3:=aVector(-1.0, 1.0,-1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0, 1.0, 1.0);
v2:=aVector(-1.0, 1.0,-1.0);
v3:=aVector(-1.0, 1.0, 1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
v1:=aVector(1.0, 1.0, 1.0);
v2:=aVector(-1.0, 1.0, 1.0);
v3:=aVector(1.0,-1.0, 1.0);
p:=v3dCreatePoly(v1,v2,v3);
v3dAddPolyToObject(o,p);
cube:=o;
end;
begin
theObject:=cube;
theObject.position.z:=10;
initGFXsystem(width,height,fullscreen);
initInputSystem(gfxInputMessanger);
repeat
fastfill(vscreen.data,vscreen.width*vscreen.height,0);
move;
v3dRenderObject(theObject);
updateGFXsystem;
updateInputSystem(gfxMessanger);
until gfxDone or keyboard[KEY_ESCAPE];
finishGFXsystem;
closeInputSystem;
ReturnFPSstring;
end.