r_misc.pas
来自「雷神之锤2(Quake2)Delphi源码」· PAS 代码 · 共 641 行 · 第 1/2 页
PAS
641 行
begin
PInteger(Integer(pindex)+(j*SizeOf(Integer)))^ := j;
PInteger(Integer(pindex)+((j+3)*SizeOf(Integer)))^ := j+3;
end
else
begin
PInteger(Integer(pindex)+(j*SizeOf(Integer)))^ := j+3;
PInteger(Integer(pindex)+((j+3)*SizeOf(Integer)))^ := j;
end;
end;
// FIXME: do just once at start
pfrustum_indexes[i] := pindex;
Inc(Integer(pindex), 6);
end;
end;
(*
===============
R_ViewChanged
Called every time the vid structure or r_refdef changes.
Guaranteed to be called before the first refresh
===============
*)
procedure R_ViewChanged(vr : vrect_p);
var
i : Integer;
begin
r_refdef.vrect := vr^;
r_refdef.horizontalFieldOfView := 2*tan(r_newrefdef.fov_x/360*M_PI);;
verticalFieldOfView := 2*tan(r_newrefdef.fov_y/360*M_PI);
r_refdef.fvrectx := r_refdef.vrect.x;
r_refdef.fvrectx_adj := r_refdef.vrect.x - 0.5;
r_refdef.vrect_x_adj_shift20 := (r_refdef.vrect.x shl 20) + (1 shr 19) - 1;
r_refdef.fvrecty := r_refdef.vrect.y;
r_refdef.fvrecty_adj := r_refdef.vrect.y - 0.5;
r_refdef.vrectright := r_refdef.vrect.x + r_refdef.vrect.width;
r_refdef.vrectright_adj_shift20 := (r_refdef.vrectright shl 20) + (1 shr 19) - 1;
r_refdef.fvrectright := r_refdef.vrectright;
r_refdef.fvrectright_adj := r_refdef.vrectright - 0.5;
r_refdef.vrectrightedge := r_refdef.vrectright - 0.99;
r_refdef.vrectbottom := r_refdef.vrect.y + r_refdef.vrect.height;
r_refdef.fvrectbottom := r_refdef.vrectbottom;
r_refdef.fvrectbottom_adj := r_refdef.vrectbottom - 0.5;
r_refdef.aliasvrect.x := Round(r_refdef.vrect.x * r_aliasuvscale);
r_refdef.aliasvrect.y := Round(r_refdef.vrect.y * r_aliasuvscale);
r_refdef.aliasvrect.width := Round(r_refdef.vrect.width * r_aliasuvscale);
r_refdef.aliasvrect.height := Round(r_refdef.vrect.height * r_aliasuvscale);
r_refdef.aliasvrectright := r_refdef.aliasvrect.x + r_refdef.aliasvrect.width;
r_refdef.aliasvrectbottom := r_refdef.aliasvrect.y + r_refdef.aliasvrect.height;
xOrigin := r_refdef.xOrigin;
yOrigin := r_refdef.yOrigin;
// values for perspective projection
// if math were exact, the values would range from 0.5 to to range+0.5
// hopefully they wll be in the 0.000001 to range+.999999 and truncate
// the polygon rasterization will never render in the first row or column
// but will definately render in the [range] row and column, so adjust the
// buffer origin to get an exact edge to edge fill
xcenter := (r_refdef.vrect.width * XCENTERING) + r_refdef.vrect.x - 0.5;
aliasxcenter := xcenter * r_aliasuvscale;
ycenter := (r_refdef.vrect.height * YCENTERING) + r_refdef.vrect.y - 0.5;
aliasycenter := ycenter * r_aliasuvscale;
xscale := r_refdef.vrect.width / r_refdef.horizontalFieldOfView;
aliasxscale := xscale * r_aliasuvscale;
xscaleinv := 1.0 / xscale;
yscale := xscale;
aliasyscale := yscale * r_aliasuvscale;
yscaleinv := 1.0 / yscale;
xscaleshrink := (r_refdef.vrect.width-6)/r_refdef.horizontalFieldOfView;
yscaleshrink := xscaleshrink;
// left side clip
screenedge[0].normal[0] := -1.0 / (xOrigin*r_refdef.horizontalFieldOfView);
screenedge[0].normal[1] := 0;
screenedge[0].normal[2] := 1;
screenedge[0]._type := PLANE_ANYZ;
// right side clip
screenedge[1].normal[0] := 1.0 / ((1.0-xOrigin)*r_refdef.horizontalFieldOfView);
screenedge[1].normal[1] := 0;
screenedge[1].normal[2] := 1;
screenedge[1]._type := PLANE_ANYZ;
// top side clip
screenedge[2].normal[0] := 0;
screenedge[2].normal[1] := -1.0 / (yOrigin*verticalFieldOfView);
screenedge[2].normal[2] := 1;
screenedge[2]._type := PLANE_ANYZ;
// bottom side clip
screenedge[3].normal[0] := 0;
screenedge[3].normal[1] := 1.0 / ((1.0-yOrigin)*verticalFieldOfView);
screenedge[3].normal[2] := 1;
screenedge[3]._type := PLANE_ANYZ;
for i := 0 to 3 do
VectorNormalize(screenedge[i].normal);
D_ViewChanged;
end;
(*
===============
R_SetupFrame
===============
*)
procedure R_SetupFrame;
var
i : Integer;
vrect : vrect_t;
begin
if (r_fullbright^.modified) then
begin
r_fullbright^.modified := false;
D_FlushCaches; // so all lighting changes
end;
Inc(r_framecount);
// build the transformation matrix for the given view angles
VectorCopy(r_refdef.vieworg, modelorg);
VectorCopy(r_refdef.vieworg, r_origin);
AngleVectors(r_refdef.viewangles, @vpn, @vright, @vup);
// current viewleaf
if ((r_newrefdef.rdflags and RDF_NOWORLDMODEL) = 0) then
begin
r_viewleaf := Mod_PointInLeaf(r_origin, r_worldmodel);
r_viewcluster := r_viewleaf^.cluster;
end;
if ((sw_waterwarp^.value <> 0.0) and ((r_newrefdef.rdflags and RDF_UNDERWATER) <> 0)) then
r_dowarp := true
else
r_dowarp := false;
if (r_dowarp) then
begin // warp into off screen buffer
vrect.x := 0;
vrect.y := 0;
if r_newrefdef.width < WARP_WIDTH then
vrect.width := r_newrefdef.width
else
vrect.width := WARP_WIDTH;
if r_newrefdef.height < WARP_HEIGHT then
vrect.height := r_newrefdef.height
else
vrect.height := WARP_HEIGHT;
d_viewbuffer := @r_warpbuffer;
r_screenwidth := WARP_WIDTH;
end
else
begin
vrect.x := r_newrefdef.x;
vrect.y := r_newrefdef.y;
vrect.width := r_newrefdef.width;
vrect.height := r_newrefdef.height;
d_viewbuffer := vid.buffer;
r_screenwidth := vid.rowbytes;
end;
R_ViewChanged(@vrect);
// start off with just the four screen edge clip planes
R_TransformFrustum;
R_SetUpFrustumIndexes;
// save base values
VectorCopy(vpn, base_vpn);
VectorCopy(vright, base_vright);
VectorCopy(vup, base_vup);
// clear frame counts
c_faceclip := 0;
d_spanpixcount := 0;
r_polycount := 0;
r_drawnpolycount := 0;
r_wholepolycount := 0;
r_amodels_drawn := 0;
r_outofsurfaces := 0;
r_outofedges := 0;
// d_setup
d_roverwrapped := false;
d_initial_rover := sc_rover;
d_minmip := Round(sw_mipcap^.value);
if (d_minmip > 3) then
d_minmip := 3
else
if (d_minmip < 0) then
d_minmip := 0;
for I := 0 to NUM_MIPS-2 do
d_scalemip[i] := basemip[i] * sw_mipscale^.value;
d_aflatcolor := 0;
end;
{$IFNDEF id386}
(*
================
R_SurfacePatch
================
*)
procedure R_SurfacePatch;
begin
// we only patch code on Intel
end;
{$ENDIF}
(*
==============================================================================
SCREEN SHOTS
==============================================================================
*)
(*
==============
WritePCXfile
==============
*)
procedure WritePCXfile(filename : PChar; data : PByte; width, height, rowbytes : Integer; palette : PByte);
var
i, j : Integer;
length : Integer;
pcx : pcx_p;
pack : PByte;
f : File;
begin
GetMem(pcx,width*height*2+1000);
if (pcx = nil) then
Exit;
pcx^.manufacturer := #$0a; // PCX id
pcx^.version := #5; // 256 color
pcx^.encoding := #1; // uncompressed
pcx^.bits_per_pixel := #8; // 256 color
pcx^.xmin := 0;
pcx^.ymin := 0;
pcx^.xmax := LittleShort((width-1));
pcx^.ymax := LittleShort((height-1));
pcx^.hres := LittleShort(width);
pcx^.vres := LittleShort(height);
FillChar(pcx^.palette,SizeOf(pcx^.palette),0);
pcx^.color_planes := 1; // chunky image
pcx^.bytes_per_line := LittleShort(width);
pcx^.palette_type := LittleShort(2); // not a grey scale
FillChar(pcx^.filler,SizeOf(pcx^.filler),0);
// pack the image
pack := @pcx^.data;
for I := 0 to height-1 do
begin
for j := 0 to width-1 do
begin
if ((data^ and $c0) <> $c0) then
begin
pack^ := data^;
Inc(Integer(pack));
Inc(Integer(data));
end
else
begin
pack^ := $c1;
Inc(Integer(pack));
pack^ := data^;
Inc(Integer(pack));
Inc(Integer(data));
end;
end;
Inc(Integer(data),rowbytes - width);
end;
// write the palette
pack^ := $0c; // palette ID byte
Inc(Integer(pack));
for i := 0 to 768-1 do
begin
pack^ := palette^;
Inc(Integer(pack));
Inc(Integer(palette));
end;
// write output file
length := Integer(pack) - Integer(pcx);
AssignFile(f, filename);
Rewrite(f,1);
//ri.Con_Printf (PRINT_ALL, "Failed to open to %s\n", filename);
BlockWrite(f, pcx, length);
CloseFile(f);
FreeMem(pcx);
end;
procedure R_ScreenShot_f; cdecl;
begin
end;
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?