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 + -
显示快捷键?