📄 gl_warp.pas
字号:
(*
glBegin (GL_POLYGON);
for (i=0 ; i<nump ; i++, vecs+=3)
{
VectorAdd(vecs, r_origin, v);
qglVertex3fv (v);
}
glEnd();
return;
*)
// decide which face it maps to
VectorCopy(vec3_origin, v);
vp := vecs;
for i := 0 to nump - 1 do
begin
VectorAdd(vp^, v, v);
Inc(vp);
end;
av[0] := abs(v[0]);
av[1] := abs(v[1]);
av[2] := abs(v[2]);
if (av[0] > av[1]) and (av[0] > av[2]) then
begin
if (v[0] < 0) then
axis := 1
else
axis := 0
end
else
begin
if (av[1] > av[2]) and (av[1] > av[0]) then
begin
if (v[1] < 0) then
axis := 3
else
axis := 2
end
else
begin
if (v[2] < 0) then
axis := 5
else
axis := 4;
end;
end;
// project new texture coords
for i := 0 to nump - 1 do
begin
j := vec_to_st[axis][2];
if (j > 0) then
dv := vecs[j - 1]
else
dv := -vecs[-j - 1];
if (dv < 0.001) then
goto continue_; // don't divide by zero
j := vec_to_st[axis][0];
if (j < 0) then
s := -vecs[-j - 1] / dv
else
s := vecs[j - 1] / dv;
j := vec_to_st[axis][1];
if (j < 0) then
t := -vecs[-j - 1] / dv
else
t := vecs[j - 1] / dv;
if (s < skymins[0][axis]) then
skymins[0][axis] := s;
if (t < skymins[1][axis]) then
skymins[1][axis] := t;
if (s > skymaxs[0][axis]) then
skymaxs[0][axis] := s;
if (t > skymaxs[1][axis]) then
skymaxs[1][axis] := t;
continue_:
inc(vecs);
end;
end; //procedure
const
ON_EPSILON = 0.1; // point on plane side epsilon
MAX_CLIP_VERTS = 64;
procedure ClipSkyPolygon(nump: integer; vecs: vec3_p; stage: integer);
var
norm: vec3_p;
v: vec3_p;
front, back: qboolean;
d, e: Single;
dists: array[0..MAX_CLIP_VERTS - 1] of Single;
sides: array[0..MAX_CLIP_VERTS - 1] of integer;
newv: array[0..1, 0..MAX_CLIP_VERTS - 1] of vec3_t;
newc: array[0..1] of integer;
i, j: integer;
label
continue_;
begin
if (nump > MAX_CLIP_VERTS - 2) then
ri.Sys_Error(ERR_DROP, 'ClipSkyPolygon: MAX_CLIP_VERTS', []);
if (stage = 6) then
begin
// fully clipped, so draw it
DrawSkyPolygon(nump, vecs);
Exit;
end;
front := false;
back := false;
norm := @skyclip[stage];
v := vecs;
i := 0;
while (i<nump) do
begin
d := DotProduct(v^, norm^);
if (d > ON_EPSILON) then
begin
front := true;
sides[i] := SIDE_FRONT;
end
else
if (d < -ON_EPSILON) then
begin
back := true;
sides[i] := SIDE_BACK;
end
else
sides[i] := SIDE_ON;
dists[i] := d;
inc(i);
Inc(v);
end;
if (not front) or (not back) then
begin
// not clipped
ClipSkyPolygon(nump, vecs, stage + 1);
Exit;
end;
// clip it
sides[i] := sides[0];
dists[i] := dists[0];
VectorCopy(vecs^, vec3_p(Pointer(Cardinal(vecs)+i*3*sizeof(Single)))^);
newc[1] := 0;
newc[0] := 0;
v := vecs;
for i := 0 to nump - 1 do
begin
case (sides[i]) of
SIDE_FRONT:
begin
VectorCopy(v^, newv[0][newc[0]]);
Inc(newc[0]);
end;
SIDE_BACK:
begin
VectorCopy(v^, newv[1][newc[1]]);
Inc(newc[1]);
end;
SIDE_ON:
begin
VectorCopy(v^, newv[0][newc[0]]);
Inc(newc[0]);
VectorCopy(v^, newv[1][newc[1]]);
Inc(newc[1]);
end;
end; //case
if (sides[i] = SIDE_ON) or (sides[i + 1] = SIDE_ON) or (sides[i + 1] = sides[i]) then
goto continue_;
d := dists[i] / (dists[i] - dists[i + 1]);
for j := 0 to 2 do
begin
e := v[j] + d * (v[j + 3] - v[j]);
newv[0][newc[0]][j] := e;
newv[1][newc[1]][j] := e;
end;
Inc(newc[0]);
Inc(newc[1]);
continue_:
Inc(v);
end;
// continue
ClipSkyPolygon(newc[0], @newv[0][0], stage + 1);
ClipSkyPolygon(newc[1], @newv[1][0], stage + 1);
end; //procedure
{*
=================
R_AddSkySurface
=================
*}
procedure R_AddSkySurface(fa: msurface_p);
var
i: integer;
verts: array[0..MAX_CLIP_VERTS - 1] of vec3_t;
p: glpoly_p;
begin
// calculate vertex values for sky box
p := fa.polys;
while p <> nil do
begin
for i := 0 to p.numverts - 1 do
VectorSubtract(vec3_p(@p^.verts[i])^, r_origin, verts[i]);
ClipSkyPolygon(p^.numverts, @verts[0], 0);
p := p.next;
end;
end; //procedure
{*
==============
R_ClearSkyBox
==============
*}
procedure R_ClearSkyBox;
var
i: integer;
begin
for i := 0 to 5 do
begin
skymins[0][i] := 9999;
skymins[1][i] := 9999;
skymaxs[0][i] := -9999;
skymaxs[1][i] := -9999;
end;
end; //procedure
procedure MakeSkyVec(s, t: Single; axis: integer);
var
v, b: vec3_t;
j, k: integer;
begin
b[0] := s * 2300;
b[1] := t * 2300;
b[2] := 2300;
for j := 0 to 2 do
begin
k := st_to_vec[axis][j];
if (k < 0) then
v[j] := -b[-k - 1]
else
v[j] := b[k - 1];
end;
// avoid bilerp seam
s := (s + 1) * 0.5;
t := (t + 1) * 0.5;
if (s < sky_min) then
s := sky_min
else
if (s > sky_max) then
s := sky_max;
if (t < sky_min) then
t := sky_min
else
if (t > sky_max) then
t := sky_max;
t := 1.0 - t;
qglTexCoord2f(s, t);
qglVertex3fv(@v);
end; //procedure
{*
==============
R_DrawSkyBox
==============
*}
const
skytexorder: array[0..5] of integer = (0, 2, 1, 3, 4, 5);
procedure R_DrawSkyBox;
var
i: integer;
begin
(*#if 0
qglEnable (GL_BLEND);
GL_TexEnv( GL_MODULATE );
qglColor4f (1,1,1,0.5);
qglDisable (GL_DEPTH_TEST);
#endif*)
if (skyrotate <> 0) then
begin
// check for no sky at all
i := 0;
while (i<6) do
begin
if (skymins[0][i] < skymaxs[0][i]) and (skymins[1][i] < skymaxs[1][i]) then
Break;
Inc(i);
end;
if (i = 6) then
Exit; // nothing visible
end;
qglPushMatrix();
qglTranslatef(r_origin[0], r_origin[1], r_origin[2]);
qglRotatef(r_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]);
for i := 0 to 5 do
begin
if (skyrotate <> 0) then
begin
// hack, forces full sky to draw when rotating
skymins[0][i] := -1;
skymins[1][i] := -1;
skymaxs[0][i] := 1;
skymaxs[1][i] := 1;
end;
if (skymins[0][i] >= skymaxs[0][i]) or (skymins[1][i] >= skymaxs[1][i]) then
Continue;
GL_Bind(sky_images[skytexorder[i]].texnum);
qglBegin(GL_QUADS);
MakeSkyVec(skymins[0][i], skymins[1][i], i);
MakeSkyVec(skymins[0][i], skymaxs[1][i], i);
MakeSkyVec(skymaxs[0][i], skymaxs[1][i], i);
MakeSkyVec(skymaxs[0][i], skymins[1][i], i);
qglEnd();
end; //for i
qglPopMatrix();
(*#if 0
glDisable (GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor4f (1,1,1,0.5);
glEnable (GL_DEPTH_TEST);
#endif*)
end; //procedure
{*
============
R_SetSky
============
*}
const
// 3dstudio environment map names
suf: array[0..5] of PChar = ('rt', 'bk', 'lf', 'ft', 'up', 'dn');
procedure R_SetSky(name: PChar; rotate: Single; axis: vec3_p); cdecl; //for gl_rmain
var
i: integer;
pathname: array[0..MAX_QPATH-1] of char;
begin
strncpy(skyname, name, sizeof(skyname) - 1);
skyrotate := rotate;
VectorCopy(axis^, skyaxis);
for i := 0 to 5 do
begin
// chop down rotating skies for less memory
if (gl_skymip.value <> 0) or (skyrotate <> 0) then
gl_picmip.value := gl_picmip.value + 1;
if Assigned(qglColorTableEXT) and (gl_ext_palettedtexture.value <> 0) then
Com_sprintf(pathname, sizeof(pathname), 'env/%s%s.pcx', [skyname, suf[i]])
else
Com_sprintf(pathname, sizeof(pathname), 'env/%s%s.tga', [skyname, suf[i]]);
sky_images[i] := GL_FindImage(pathname, it_sky);
if (sky_images[i] = nil) then
sky_images[i] := r_notexture;
if (gl_skymip.value <> 0) or (skyrotate <> 0) then
begin
// take less memory
gl_picmip.value := gl_picmip.value - 1;
sky_min := 1.0 / 256;
sky_max := 255.0 / 256;
end
else
begin
sky_min := 1.0 / 512;
sky_max := 511.0 / 512;
end;
end; //for i
end; //procedure
// End of file
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -