📄 gl_warp.pas
字号:
// PLEASE, don't modify this file
// 81% complete
{----------------------------------------------------------------------------}
{ }
{ File(s): gl_warp.c -- sky and water polygons }
{ }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru }
{ Initial conversion on : 16-Jan-2002 }
{ }
{ This File contains part of convertion of Quake2 source to ObjectPascal. }
{ More information about this project can be found at: }
{ http://www.sulaco.co.za/quake2/ }
{ }
{ Copyright (C) 1997-2001 Id Software, Inc. }
{ }
{ This program is free software; you can redistribute it and/or }
{ modify it under the terms of the GNU General Public License }
{ as published by the Free Software Foundation; either version 2 }
{ of the License, or (at your option) any later version. }
{ }
{ This program is distributed in the hope that it will be useful, }
{ but WITHOUT ANY WARRANTY; without even the implied warranty of }
{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. }
{ }
{ See the GNU General Public License for more details. }
{ }
{----------------------------------------------------------------------------}
{ Updated on : }
{ Updated by : }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ }
{ x) warpsin.inc }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1) Do more tests }
{ }
{----------------------------------------------------------------------------}
// gl_warp.c -- sky and water polygons
unit gl_warp;
interface
uses q_shared, gl_model_h;
procedure GL_SubdivideSurface (fa : msurface_p); //for gl_model
procedure R_SetSky (name : PChar; rotate : float; axis : vec3_t); cdecl; //for gl_rmain
implementation
uses Ref, gl_local, GL, qgl_win, gl_image;// Math_procedure Xxx(); overload;{$I OVERLOAD_need_remove.inc}
var
//extern model_t *loadmodel;
loadmodel : model_p;
(*
char skyname[MAX_QPATH];
float skyrotate;
vec3_t skyaxis;
image_t *sky_images[6];
msurface_t *warpface;*)
skyname : array [0..MAX_QPATH-1] of char;
skyrotate : float;
skyaxis : vec3_t;
sky_images : array [0..5] of image_p;
warpface : msurface_p;
const
SUBDIVIDE_SIZE = 64;
//id: #define SUBDIVIDE_SIZE 1024
//void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
procedure BoundPoly (numverts : integer; verts : Pfloat; mins, maxs : vec3_t);
var
i, j : integer;
// float *v;
v : Pfloat;
begin
mins[0] := 9999;
mins[1] := mins[0];
mins[2] := mins[0];
maxs[0] := -9999;
maxs[1] := maxs[0];
maxs[2] := maxs[0];
v := verts;
for i:=0 to numverts-1 do
for j:=0 to 2 do
begin
(* if (*v < mins[j])
mins[j] = *v;
if (*v > maxs[j])
maxs[j] = *v;*)
if (v^ < mins[j]) then
mins[j] := v^;
if (v^ > maxs[j]) then
maxs[j] := v^;
Inc(v);
end;
end; //procedure
//void SubdividePolygon (int numverts, float *verts)
//{Y} Recursion procedure
procedure SubdividePolygon (numverts : integer; verts : Pfloat); //verts : PFloatArray OR "array of float"
var
i, j, k : integer;
mins,
maxs : vec3_t;
m : float;
// float *v;
v : Pfloat;
_v : vec3_p;
front,
back : array [0..63] of vec3_t;
f, b : integer;
dist : array [0..63] of float;
frac : float;
// glpoly_t *poly;
poly : glpoly_p;
total : vec3_t;
s, t,
total_s,
total_t : float;
begin
if (numverts > 60) then
ri.Sys_Error (ERR_DROP, 'numverts = %i', [numverts]);
BoundPoly (numverts, verts, mins, maxs);
for i:=0 to 2 do
begin
m := (mins[i] + maxs[i]) * 0.5;
m := SUBDIVIDE_SIZE * Floor (m/SUBDIVIDE_SIZE + 0.5);
if (maxs[i] - m < 8) then
Continue;
if (m - mins[i] < 8) then
Continue;
// cut it
{ v := verts + i;
for (j=0 ; j<numverts ; j++, v+= 3)
dist[j] = *v - m;}
v := verts;
Inc(v, i);
for j:=0 to numverts-1 do
begin
dist[j] := v^ - m;
Inc(v, 3);
end;
// wrap cases
dist[j] := dist[0];
Dec(v, i);
VectorCopy (verts, v);
f := 0;
b := 0;
v := pfloat(verts);
//{Y} for (j=0 ; j<numverts ; j++, v+= 3)
for j:=0 to numverts-1 do
begin
if (dist[j] >= 0) then
begin
VectorCopy (v, front[f]);
Inc(f);
end;
if (dist[j] <= 0) then
begin
VectorCopy (v, back[b]);
Inc(b);
end;
if (dist[j] = 0) OR (dist[j+1] = 0) then
Continue;
if ( (dist[j] > 0) <> (dist[j+1] > 0) ) then
begin
// clip point
frac := dist[j] / (dist[j] - dist[j+1]);
for k:=0 to 2 do
begin
//Y front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
// back[b][k] := v[k] + frac*(v[3+k] - v[k]);
_v := vec3_p(v);
back[b][k] := _v[k] + frac*(_v[3+k] - _v[k]);
front[f][k] := back[b][k];
end;
Inc(f);
Inc(b);
end;
Inc (v, 3);
end;//for???
SubdividePolygon (f, @front[0]); //Y: @
SubdividePolygon (b, @back[0]); //Y: @
// return; //??? - ???
Exit; //{Y} Recursion procedure
end; //for i
// add a point in the center to help keep warp valid
//Y poly := Hunk_Alloc (sizeof(glpoly_t) + ((numverts-4)+2) * VERTEXSIZE*sizeof(float));
poly.next := warpface.polys;
warpface.polys := poly;
poly.numverts := numverts+2;
VectorClear (total);
total_s := 0;
total_t := 0;
{Y} for i:=0 to numverts-1 do // ; i++, verts+= 3)
begin
VectorCopy (verts, @poly.verts[i+1]);
s := DotProduct (verts, @warpface.texinfo.vecs[0]);
t := DotProduct (verts, @warpface.texinfo.vecs[1]);
total_s := total_s +s;
total_t := total_t +t;
VectorAdd (total, verts, total);
poly.verts[i+1][3] := s;
poly.verts[i+1][4] := t;
end;//for??? i
VectorScale (total, (1.0/numverts), @poly.verts[0]);
poly.verts[0][3] := total_s/numverts;
poly.verts[0][4] := total_t/numverts;
// copy first vertex to last
// memcpy (poly.verts[i+1], poly.verts[1], sizeof(poly.verts[0]));
poly.verts[i+1] := poly.verts[1];
end;//procedure
{*
================
GL_SubdivideSurface
Breaks a polygon up along axial 64 unit
boundaries so that turbulent and sky warps
can be done reasonably.
================
*}
//void GL_SubdivideSurface (msurface_t *fa)
procedure GL_SubdivideSurface (fa : msurface_p); //for gl_model
var
verts : array [0..63] of vec3_t;
numverts,
i,
lindex : integer;
// float *vec;
vec : vec3_t;
begin
warpface := fa;
//
// convert edges back to a normal polygon
//
numverts := 0;
for i:=0 to fa.numedges-1 do
begin
lindex := loadmodel.surfedges[fa.firstedge + i];
if (lindex > 0)
then vec := loadmodel.vertexes[loadmodel.edges[lindex].v[0]].position
else vec := loadmodel.vertexes[loadmodel.edges[-lindex].v[1]].position;
VectorCopy (vec, verts[numverts]);
Inc(numverts);
end;
SubdividePolygon (numverts, @verts[0]); //Y
end;//procedure
var
// speed up sin calculations - Ed
r_turbsin : array [0..32*8-1] of float =
(
{$I ..\..\Source\warpsin.inc}
);
const
TURBSCALE = 256.0 /(2 * M_PI);
{*
=============
EmitWaterPolys
Does a water warp on the pre-fragmented glpoly_t chain
=============
*}
//void EmitWaterPolys (msurface_t *fa)
procedure EmitWaterPolys (fa : msurface_p);
var
// glpoly_t *p, *bp;
bp, p : glpoly_p;
// float *v;
i : integer;
s, t,
os, ot,
scroll,
rdt : float;
begin
rdt := r_newrefdef.time;
//{Y} if (fa->texinfo->flags & SURF_FLOWING)
if ((fa.texinfo.flags AND SURF_FLOWING) <> 0)
// then scroll := -64 * ( (r_newrefdef.time*0.5) - (int)(r_newrefdef.time*0.5) )
then scroll := -64 * Frac(r_newrefdef.time*0.5) //Y: optimize
else scroll := 0;
//Y: for (bp=fa->polys ; bp ; bp=bp->next)
bp := fa.polys;
while (bp<>Nil) do
begin
p := bp;
qglBegin (GL_TRIANGLE_FAN);
(*Y {Y}for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
begin
os := v[3];
ot := v[4];
#if !id386
s = os + r_turbsin[(int)((ot*0.125+r_newrefdef.time) * TURBSCALE) & 255];
#else
s = os + r_turbsin[Q_ftol( ((ot*0.125+rdt) * TURBSCALE) ) & 255];
#endif
s := s +scroll;
s := s *(1.0/64);
//optimize code s := (s +scroll) *invert64;
#if !id386
t = ot + r_turbsin[(int)((os*0.125+rdt) * TURBSCALE) & 255];
#else
t = ot + r_turbsin[Q_ftol( ((os*0.125+rdt) * TURBSCALE) ) & 255];
#endif
t := t *(1.0/64);
//optimize code t := t *invert64;
qglTexCoord2f (s, t);
qglVertex3fv (v);
end;//for???*)
qglEnd ();
bp := bp.next;
end;//for???
end;//procedure
const
skyclip : array [0..5] of vec3_t =
( (1,1,0),
(1,-1,0),
(0,-1,1),
(0,1,1),
(1,0,1),
(-1,0,1) );
var
c_sky : integer;
const
// 1 = s, 2 = t, 3 = 2048
st_to_vec : array [0..5, 0..2] of integer =
( (3,-1,2),
(-3,1,2),
(1,3,2),
(-1,-3,2),
(-2,-1,3), // 0 degrees yaw, look straight up
(2,-1,-3) // look straight down
// {-1,2,3},
// {1,2,-3}
);
// s = [0]/[2], t = [1]/[2]
vec_to_st : array [0..5, 0..2] of integer =
( (-2,3,1),
(2,3,-1),
(1,3,2),
(-1,3,-2),
(-2,-1,3),
(-2,1,-3)
// {-1,2,3},
// {1,2,-3}
);
var
skymins, skymaxs : array [0..1, 0..5] of float;
sky_min, sky_max : float;
procedure DrawSkyPolygon (nump : integer; vecs : vec3_t);
var
i, j,
axis : integer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -