📄 gl_rsurf.pas
字号:
_dynamic:
if (gl_dynamic.value <> 0) then
begin
// if (!( fa.texinfo.flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP ) ) ) then
if ((fa^.texinfo.flags and (SURF_SKY or SURF_TRANS33 or SURF_TRANS66 or SURF_WARP)) = 0) then
is_dynamic := true;
end;
end; //if
if (is_dynamic) then
begin
if (((fa^.styles[maps] >= 32) or (fa^.styles[maps] = 0)) and
(fa^.dlightframe <> r_framecount)) then
begin
smax := (fa^.extents[0] shr 4) + 1;
tmax := (fa^.extents[1] shr 4) + 1;
R_BuildLightMap(fa, @temp, smax * 4);
R_SetCacheState(fa);
GL_Bind(gl_state.lightmap_textures + fa.lightmaptexturenum);
qglTexSubImage2D(GL_TEXTURE_2D, 0,
fa^.light_s, fa^.light_t,
smax, tmax,
GL_LIGHTMAP_FORMAT,
GL_UNSIGNED_BYTE, @temp);
fa^.lightmapchain := gl_lms.lightmap_surfaces[fa^.lightmaptexturenum];
gl_lms.lightmap_surfaces[fa^.lightmaptexturenum] := fa;
end
else
begin
fa^.lightmapchain := gl_lms.lightmap_surfaces[0];
gl_lms.lightmap_surfaces[0] := fa;
end;
end
else
begin
fa^.lightmapchain := gl_lms.lightmap_surfaces[fa^.lightmaptexturenum];
gl_lms.lightmap_surfaces[fa^.lightmaptexturenum] := fa;
end;
end; //procedure
{*
================
R_DrawAlphaSurfaces
Draw water surfaces and windows.
The BSP tree is waled front to back, so unwinding the chain
of alpha_surfaces will draw back to front, giving proper ordering.
================
*}
procedure R_DrawAlphaSurfaces; //for gl_rmain
var
s: msurface_p;
intens: Single;
begin
//
// go back to the world matrix
//
qglLoadMatrixf(@r_world_matrix);
qglEnable(GL_BLEND);
GL_TexEnv(GL_MODULATE);
// the textures are prescaled up for a better lighting range,
// so scale it back down
intens := gl_state.inverse_intensity;
s := r_alpha_surfaces;
while (s <> nil) do
begin
GL_Bind(s.texinfo.image.texnum);
Inc(c_brush_polys);
if (s^.texinfo.flags and SURF_TRANS33) <> 0 then
qglColor4f(intens, intens, intens, 0.33)
else
if (s^.texinfo.flags and SURF_TRANS66) <> 0 then
qglColor4f(intens, intens, intens, 0.66)
else
qglColor4f(intens, intens, intens, 1);
if (s^.flags and SURF_DRAWTURB) <> 0 then
EmitWaterPolys(s)
else
if (s^.texinfo^.flags and SURF_FLOWING) <> 0 then
DrawGLFlowingPoly(s)
else
DrawGLPoly(s.polys);
s := s.texturechain;
end;
GL_TexEnv(GL_REPLACE);
qglColor4f(1, 1, 1, 1);
qglDisable(GL_BLEND);
r_alpha_surfaces := nil;
end;
{*
================
DrawTextureChains
================
*}
procedure DrawTextureChains;
var
i: integer;
s: msurface_p;
image: image_p;
label
continue1_,
continue2_,
continue3_;
begin
c_visible_textures := 0;
//idsoft GL_TexEnv( GL_REPLACE );
if (not Assigned(qglSelectTextureSGIS)) and (not Assigned(qglActiveTextureARB)) then
begin
i := 0;
image := @gltextures;
while (i < numgltextures) do
begin
if (image.registration_sequence = 0) then
goto continue1_;
s := image.texturechain;
if (s = nil) then
goto continue1_;
Inc(c_visible_textures);
while (s <> nil) do
begin
R_RenderBrushPoly(s);
s := s^.texturechain;
end;
image.texturechain := nil;
continue1_:
Inc(i);
Inc(image);
end;
end
else
begin
i := 0;
image := @gltextures;
while (i < numgltextures) do
begin
if (image.registration_sequence = 0) then
goto continue2_;
if (image.texturechain = nil) then
goto continue2_;
Inc(c_visible_textures);
s := image^.texturechain;
while (s <> nil) do
begin
if ((s.flags and SURF_DRAWTURB) = 0) then
R_RenderBrushPoly(s);
s := s^.texturechain;
end;
continue2_:
Inc(i);
Inc(image);
end;
GL_EnableMultitexture(false);
i := 0;
image := @gltextures;
while (i < numgltextures) do
begin
if (image.registration_sequence = 0) then
goto continue3_;
s := image.texturechain;
if (s = nil) then
goto continue3_;
while (s <> nil) do
begin
if (s.flags and SURF_DRAWTURB) <> 0 then
R_RenderBrushPoly(s);
s := s^.texturechain;
end;
image.texturechain := nil;
continue3_:
Inc(i);
Inc(image);
end;
//idsoft GL_EnableMultitexture( true );
end;
GL_TexEnv(GL_REPLACE);
end; //procedure
procedure GL_RenderLightmappedPoly(surf: msurface_p);
var
i, map: integer;
v: PSingle;
p: glpoly_p;
temp: array[0..128 * 128 - 1] of Cardinal;
is_dynamic: qboolean;
smax, tmax: integer;
scroll: Single;
nv: integer;
image: image_p;
lmtex: Cardinal;
label
dynamic_;
begin
is_dynamic := false;
nv := surf^.polys^.numverts;
image := R_TextureAnimation(surf^.texinfo);
lmtex := surf^.lightmaptexturenum;
map := 0;
while (map < MAXLIGHTMAPS) and (surf^.styles[map] <> 255) do
begin
if (r_newrefdef.lightstyles[surf^.styles[map]].white <> surf.cached_light[map]) then
goto dynamic_;
Inc(map);
end;
// dynamic this frame or dynamic previously
if (surf^.dlightframe = r_framecount) then
begin
dynamic_:
if (gl_dynamic.value <> 0) then
begin
if (surf^.texinfo^.flags and (SURF_SKY or SURF_TRANS33 or SURF_TRANS66 or SURF_WARP) = 0) then
is_dynamic := true;
end;
end;
if (is_dynamic) then
begin
if (((surf^.styles[map] >= 32) or (surf^.styles[map] = 0)) and
(surf^.dlightframe <> r_framecount)) then
begin
smax := (surf^.extents[0] shr 4) + 1;
tmax := (surf^.extents[1] shr 4) + 1;
R_BuildLightMap(surf, @temp, smax * 4);
R_SetCacheState(surf);
GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures + surf^.lightmaptexturenum);
lmtex := surf^.lightmaptexturenum;
qglTexSubImage2D(GL_TEXTURE_2D, 0,
surf^.light_s, surf^.light_t,
smax, tmax,
GL_LIGHTMAP_FORMAT,
GL_UNSIGNED_BYTE, @temp);
end
else
begin
smax := (surf^.extents[0] shr 4) + 1;
tmax := (surf^.extents[1] shr 4) + 1;
R_BuildLightMap(surf, @temp, smax * 4);
GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures + 0);
lmtex := 0;
qglTexSubImage2D(GL_TEXTURE_2D, 0,
surf^.light_s, surf^.light_t,
smax, tmax,
GL_LIGHTMAP_FORMAT,
GL_UNSIGNED_BYTE, @temp);
end;
Inc(c_brush_polys);
GL_MBind(GL_TEXTURE0, image^.texnum);
GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures + lmtex);
//==========
//PGM
if (surf^.texinfo^.flags and SURF_FLOWING) <> 0 then
begin
scroll := -64 * ((r_newrefdef.time / 40.0) - Trunc(r_newrefdef.time / 40.0));
if (scroll = 0.0) then
scroll := -64.0;
p := surf^.polys;
while p <> nil do
begin
v := @p.verts[0];
qglBegin(GL_POLYGON);
for i := 0 to nv - 1 do
begin
qglMTexCoord2fSGIS(GL_TEXTURE0, (PSingleArray(v)^[3] + scroll), PSingleArray(v)^[4]);
qglMTexCoord2fSGIS(GL_TEXTURE1, PSingleArray(v)^[5], PSingleArray(v)^[6]);
qglVertex3fv(PGLFloat(v));
Inc(v, VERTEXSIZE);
end;
qglEnd();
p := p.chain;
end;
end
else
begin
p := surf^.polys;
while p <> nil do
begin
v := @p^.verts[0];
qglBegin(GL_POLYGON);
for i := 0 to nv - 1 do
begin
qglMTexCoord2fSGIS(GL_TEXTURE0, PSingleArray(v)^[3], PSingleArray(v)^[4]);
qglMTexCoord2fSGIS(GL_TEXTURE1, PSingleArray(v)^[5], PSingleArray(v)^[6]);
qglVertex3fv(PGLFloat(v));
Inc(v, VERTEXSIZE);
end;
qglEnd();
p := p^.chain;
end;
end;
//PGM
//==========
end //then
else
begin
Inc(c_brush_polys);
GL_MBind(GL_TEXTURE0, image^.texnum);
GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures + lmtex);
//==========
//PGM
if (surf^.texinfo^.flags and SURF_FLOWING) <> 0 then
begin
scroll := -64 * ((r_newrefdef.time / 40.0) - Trunc(r_newrefdef.time / 40.0));
if (scroll = 0.0) then
scroll := -64.0;
p := surf^.polys;
while p <> nil do
begin
v := @p^.verts[0];
qglBegin(GL_POLYGON);
for i := 0 to nv - 1 do
begin
qglMTexCoord2fSGIS(GL_TEXTURE0, (PSingleArray(v)^[3] + scroll), PSingleArray(v)^[4]);
qglMTexCoord2fSGIS(GL_TEXTURE1, PSingleArray(v)^[5], PSingleArray(v)^[6]);
qglVertex3fv(PGLFloat(v));
Inc(v, VERTEXSIZE);
end;
qglEnd();
p := p^.chain;
end;
end
else
begin
//PGM
//==========
p := surf^.polys;
while p <> nil do
begin
v := @p^.verts[0];
qglBegin(GL_POLYGON);
for i := 0 to nv - 1 do
begin
qglMTexCoord2fSGIS(GL_TEXTURE0, PSingleArray(v)^[3], PSingleArray(v)^[4]);
qglMTexCoord2fSGIS(GL_TEXTURE1, PSingleArray(v)^[5], PSingleArray(v)^[6]);
qglVertex3fv(PGLFloat(v));
Inc(v, VERTEXSIZE);
end;
qglEnd();
p := p^.chain;
end;
//==========
//PGM
end;
//PGM
//==========
end;
end; //procedure
{*
=================
R_DrawInlineBModel
=================
*}
procedure R_DrawInlineBModel;
var
i, k: integer;
pplane: cplane_p;
dot: Single;
psurf: msurface_p;
lt: dlight_p;
begin
// calculate dynamic lighting for bmodel
if (gl_flashblend^.value = 0) then
begin
lt := r_newrefdef.dlights;
k := 0;
while (k < r_newrefdef.num_dlights) do
begin
R_MarkLights(lt, 1 shl k, Pointer(Cardinal(currentmodel^.nodes) + (currentmodel^.firstnode * sizeof(mnode_t))));
Inc(k);
Inc(lt);
end;
end;
psurf := @currentmodel^.surfaces[currentmodel^.firstmodelsurface];
if (currententity.flags and RF_TRANSLUCENT) <> 0 then
begin
qglEnable(GL_BLEND);
qglColor4f(1, 1, 1, 0.25);
GL_TexEnv(GL_MODULATE);
end;
//
// draw texture
//
for i := 0 to currentmodel^.nummodelsurfaces - 1 do
begin
// find which side of the node we are on
pplane := psurf^.plane;
dot := DotProduct(modelorg, pplane^.normal) - pplane^.dist;
// draw the polygon
if ((((psurf^.flags and SURF_PLANEBACK) <> 0) and (dot < -BACKFACE_EPSILON)) or
(((psurf^.flags and SURF_PLANEBACK) = 0) and (dot > BACKFACE_EPSILON))) then
begin
if (psurf^.texinfo^.flags and (SURF_TRANS33 or SURF_TRANS66) <> 0) then
begin
// add to the translucent chain
psurf^.texturechain := r_alpha_surfaces;
r_alpha_surfaces := psurf;
end
else
if (Assigned(qglMTexCoord2fSGIS) and ((psurf.flags and SURF_DRAWTURB) = 0)) then
GL_RenderLightmappedPoly(psurf)
else
begin
GL_EnableMultitexture(false);
R_RenderBrushPoly(psurf);
GL_EnableMultitexture(true);
end;
end; //if
inc(psurf);
end;
if ((currententity.flags and RF_TRANSLUCENT) = 0) then
begin
if not Assigned(qglMTexCoord2fSGIS) then
R_BlendLightmaps();
end
else
begin
qglDisable(GL_BLEND);
qglColor4f(1, 1, 1, 1);
GL_TexEnv(GL_REPLACE);
end;
end; //procedure
{*
=================
R_DrawBrushModel
=================
*}
procedure R_DrawBrushModel(e: entity_p); //for gl_rmain
var
i: integer;
rotated: qboolean;
mins, maxs,
temp,
forward_,
right, up: vec3_t;
begin
if (currentmodel^.nummodelsurfaces = 0) then
Exit;
currententity := e;
gl_state.currenttextures[0] := -1;
gl_state.currenttextures[1] := -1;
if (e^.angles[0] <> 0) or (e^.angles[1] <> 0) or (e^.angles[2] <> 0) then
begin
rotated := true;
for i := 0 to 2 do
begin
mins[i] := e^.origin[i] - currentmodel^.radius;
maxs[i] := e^.origin[i] + currentmodel^.radius;
end;
end
else
begin
rotated := false;
VectorAdd(vec3_t(e^.origin), currentmodel^.mins, mins);
VectorAdd(vec3_t(e^.origin), currentmodel^.maxs, maxs);
end;
if (R_CullBox(mins, maxs)) then
Exit;
qglColor3f(1, 1, 1);
FillChar(gl_lms.lightmap_surfaces, sizeof(gl_lms.lightmap_surfaces), 0);
VectorSubtract(vec3_t(r_newrefdef.vieworg), vec3_t(e^.origin), modelorg);
if (rotated) then
begin
VectorCopy(modelorg, temp);
AngleVectors(vec3_t(e^.angles), @forward_, @right, @up);
modelorg[0] := DotProduct(temp, forward_);
modelorg[1] := -DotProduct(temp, right);
modelorg[2] := DotProduct(temp, up);
end;
qglPushMatrix();
e^.angles[0] := -e^.angles[0]; // stupid quake bug
e^.angles[2] := -e^.angles[2]; // stupid quake bug
R_RotateForEntity(e);
e^.angles[0] := -e^.angles[0]; // stupid quake bug
e^.angles[2] := -e^.angles[2]; // stupid quake bug
GL_EnableMultitexture(true);
GL_SelectTexture(GL_TEXTURE0);
GL_TexEnv(GL_REPLACE);
GL_SelectTexture(GL_TEXTURE1);
GL_TexEnv(GL_MODULATE);
R_DrawInlineBModel();
GL_EnableMultitexture(false);
qglPopMatrix();
end;
{*
=============================================================
WORLD MODEL
=============================================================
*}
{*
================
R_RecursiveWorldNode
================
*}
procedure R_RecursiveWorldNode(node: mnode_p);
var
c, side, sidebit: integer;
plane: cplane_p;
surf: msurface_p;
mark: msurface_pp;
pleaf: mleaf_p;
dot: Single;
image: image_p;
notside_: Integer;
label
Continue_;
begin
if (node^.contents = CONTENTS_SOLID) then
Exit; // solid
if (node^.visframe <> r_visframecount) then
Exit;
if (R_CullBox(vec3_p(@node^.minmaxs)^, vec3_p(@node^.minmaxs[3])^)) then
Exit;
// if a leaf node, draw stuff
if (node.contents <> -1) then
begin
pleaf := mleaf_p(node);
// check for door connected areas
if (r_newrefdef.areabits <> nil) then
begin
if ((PByteArray(r_newrefdef.areabits)[pleaf^.area shr 3] and (1 shl (pleaf^.area and 7))) = 0) then
Exit; // not visible
end;
mark := pleaf^.firstmarksurface;
c := pleaf^.nummarksurfaces;
if (c <> 0) then
begin
repeat
mark^^.visFrame := r_framecount;
Inc(mark);
Dec(c);
until (c = 0);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -