📄 gl_rmain.pas
字号:
if (currentmodel = nil) then
begin
R_DrawNullModel();
Continue;
end;
case currentmodel._type of
mod_alias: R_DrawAliasModel(currententity);
mod_brush: R_DrawBrushModel(currententity);
mod_sprite: R_DrawSpriteModel(currententity);
else
ri.Sys_Error(ERR_DROP, 'Bad modeltype', []);
end;
end;
end;
qglDepthMask(True); // back to writing
end;
{*
** GL_DrawParticles
**
*}
//procedure GL_DrawParticles( int num_particles, const particle_t particles[], const unsigned colortable[768] );
procedure GL_DrawParticles(num_particles: integer; particles: particle_p; colortable: PCardinalArray);
var
p: particle_p;
i: integer;
up, right: vec3_t;
scale: Single;
color: array[0..3] of byte;
begin
GL_Bind(r_particletexture.texnum);
qglDepthMask(False); // no z buffering
qglEnable(GL_BLEND);
GL_TexEnv(GL_MODULATE);
qglBegin(GL_TRIANGLES);
VectorScale(vup, 1.5, up);
VectorScale(vright, 1.5, right);
p := particles;
for i := 0 to num_particles - 1 do
begin
// hack a scale up to keep particles from disapearing
scale := (p.origin[0] - r_origin[0]) * vpn[0] +
(p.origin[1] - r_origin[1]) * vpn[1] +
(p.origin[2] - r_origin[2]) * vpn[2];
if (scale < 20) then
scale := 1
else
scale := 1 + scale * 0.004;
PInteger(@color)^ := colortable[p.color];
color[3] := Trunc(p.alpha * 255);
qglColor4ubv(@color);
qglTexCoord2f(0.0625, 0.0625);
qglVertex3fv(@p.origin);
qglTexCoord2f(1.0625, 0.0625);
qglVertex3f(p.origin[0] + up[0] * scale,
p.origin[1] + up[1] * scale,
p.origin[2] + up[2] * scale);
qglTexCoord2f(0.0625, 1.0625);
qglVertex3f(p.origin[0] + right[0] * scale,
p.origin[1] + right[1] * scale,
p.origin[2] + right[2] * scale);
Inc(p);
end;
qglEnd();
qglDisable(GL_BLEND);
qglColor4f(1, 1, 1, 1);
qglDepthMask(True); // back to normal Z buffering
GL_TexEnv(GL_REPLACE);
end;
{*
===============
R_DrawParticles
===============
*}
procedure R_DrawParticles;
var
i: integer;
color: array[0..3] of byte;
p: particle_p;
begin
if (gl_ext_pointparameters.value <> 0) and Assigned(qglPointParameterfEXT) then
begin
qglDepthMask(False);
qglEnable(GL_BLEND);
qglDisable(GL_TEXTURE_2D);
qglPointSize(gl_particle_size.value);
qglBegin(GL_POINTS);
p := r_newrefdef.particles;
for i := 0 to r_newrefdef.num_particles - 1 do
begin
// *(int * )color = d_8to24table[p.color];
move(d_8to24table[p.color], color, 4);
color[3] := Trunc(p.alpha * 255);
qglColor4ubv(@color);
qglVertex3fv(@p.origin);
Inc(p);
end;
qglEnd();
qglDisable(GL_BLEND);
qglColor4f(1.0, 1.0, 1.0, 1.0);
qglDepthMask(True);
qglEnable(GL_TEXTURE_2D);
end
else
GL_DrawParticles(r_newrefdef.num_particles, r_newrefdef.particles, @d_8to24table);
end; //procedure
{*
============
R_PolyBlend
============
*}
procedure R_PolyBlend;
begin
if (gl_polyblend.value = 0) then
Exit;
if (v_blend[3] = 0) then
Exit;
qglDisable(GL_ALPHA_TEST);
qglEnable(GL_BLEND);
qglDisable(GL_DEPTH_TEST);
qglDisable(GL_TEXTURE_2D);
qglLoadIdentity();
// FIXME: get rid of these
qglRotatef(-90, 1, 0, 0); // put Z going up
qglRotatef(90, 0, 0, 1); // put Z going up
qglColor4fv(@v_blend);
qglBegin(GL_QUADS);
qglVertex3f(10, 100, 100);
qglVertex3f(10, -100, 100);
qglVertex3f(10, -100, -100);
qglVertex3f(10, 100, -100);
qglEnd();
qglDisable(GL_BLEND);
qglEnable(GL_TEXTURE_2D);
qglEnable(GL_ALPHA_TEST);
qglColor4f(1, 1, 1, 1);
end;
//=======================================================================
function SignbitsForPlane(_out: cplane_p): integer;
var
bits, j: integer;
begin
// for fast box on planeside test
bits := 0;
for j := 0 to 2 do
if (_out.normal[j] < 0) then
bits := bits or (1 shl j);
Result := bits;
end; //function
procedure R_SetFrustum;
var
i: integer;
begin
(*
/*
** this code is wrong, since it presume a 90 degree FOV both in the
** horizontal and vertical plane
*/
// front side is visible
VectorAdd (vpn, vright, frustum[0].normal);
VectorSubtract (vpn, vright, frustum[1].normal);
VectorAdd (vpn, vup, frustum[2].normal);
VectorSubtract (vpn, vup, frustum[3].normal);
// we theoretically don't need to normalize these vectors, but I do it
// anyway so that debugging is a little easier
VectorNormalize( frustum[0].normal );
VectorNormalize( frustum[1].normal );
VectorNormalize( frustum[2].normal );
VectorNormalize( frustum[3].normal );
*)
// rotate VPN right by FOV_X/2 degrees
RotatePointAroundVector(frustum[0].normal, vup, vpn, -(90 - r_newrefdef.fov_x / 2));
// rotate VPN left by FOV_X/2 degrees
RotatePointAroundVector(frustum[1].normal, vup, vpn, 90 - r_newrefdef.fov_x / 2);
// rotate VPN up by FOV_X/2 degrees
RotatePointAroundVector(frustum[2].normal, vright, vpn, 90 - r_newrefdef.fov_y / 2);
// rotate VPN down by FOV_X/2 degrees
RotatePointAroundVector(frustum[3].normal, vright, vpn, -(90 - r_newrefdef.fov_y / 2));
for i := 0 to 3 do
begin
frustum[i]._type := PLANE_ANYZ;
frustum[i].dist := DotProduct(r_origin, frustum[i].normal);
frustum[i].signbits := SignbitsForPlane(@frustum[i]);
end;
end; //procedure
//=======================================================================
{*
===============
R_SetupFrame
===============
*}
procedure R_SetupFrame;
var
i: integer;
leaf: mleaf_p;
temp: vec3_t;
begin
Inc(r_framecount);
// build the transformation matrix for the given view angles
VectorCopy(vec3_t(r_newrefdef.vieworg), r_origin);
AngleVectors(vec3_t(r_newrefdef.viewangles), @vpn, @vright, @vup);
// current viewcluster
if (r_newrefdef.rdflags and RDF_NOWORLDMODEL) = 0 then
begin
r_oldviewcluster := r_viewcluster;
r_oldviewcluster2 := r_viewcluster2;
leaf := Mod_PointInLeaf(r_origin, r_worldmodel);
// r_viewcluster = r_viewcluster2 = leaf->cluster;
r_viewcluster2 := leaf.cluster;
r_viewcluster := r_viewcluster2;
// check above and below so crossing solid water doesn't draw wrong
if (leaf.contents = 0) then
begin
// look down a bit
VectorCopy(r_origin, temp);
temp[2] := temp[2] - 16;
leaf := Mod_PointInLeaf(temp, r_worldmodel);
if ((leaf.contents and CONTENTS_SOLID) = 0) and
(leaf.cluster <> r_viewcluster2) then
r_viewcluster2 := leaf.cluster;
end
else
begin
// look up a bit
VectorCopy(r_origin, temp);
temp[2] := temp[2] + 16;
leaf := Mod_PointInLeaf(temp, r_worldmodel);
if ((leaf.contents and CONTENTS_SOLID) = 0) and
(leaf.cluster <> r_viewcluster2) then
r_viewcluster2 := leaf.cluster;
end;
end;
for i := 0 to 3 do
v_blend[i] := r_newrefdef.blend[i];
c_brush_polys := 0;
c_alias_polys := 0;
// clear out the portion of the screen that the NOWORLDMODEL defines
if (r_newrefdef.rdflags and RDF_NOWORLDMODEL) <> 0 then
begin
qglEnable(GL_SCISSOR_TEST);
qglClearColor(0.3, 0.3, 0.3, 1);
qglScissor(r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y,
r_newrefdef.width, r_newrefdef.height);
qglClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
qglClearColor(1, 0, 0.5, 0.5);
qglDisable(GL_SCISSOR_TEST);
end;
end;
procedure MYgluPerspective(fovy, aspect,
zNear, zFar: TGLdouble);
var
xmin, xmax, ymin, ymax: TGLdouble;
begin
ymax := zNear * tan(fovy * M_PI / 360.0);
ymin := -ymax;
xmin := ymin * aspect;
xmax := ymax * aspect;
xmin := xmin - (2 * gl_state.camera_separation) / zNear;
xmax := xmax - (2 * gl_state.camera_separation) / zNear;
qglFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
end;
{*
=============
R_SetupGL
=============
*}
procedure R_SetupGL;
var
screenaspect: Single;
// float yfov;
x, x2, y2, y, w, h: integer;
begin
//
// set up viewport
//
x := Floor(r_newrefdef.x * vid.width / vid.width);
x2 := Ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
y := Floor(vid.height - r_newrefdef.y * vid.height / vid.height);
y2 := Ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
w := x2 - x;
h := y - y2;
qglViewport(x, y2, w, h);
//
// set up projection matrix
//
screenaspect := r_newrefdef.width / r_newrefdef.height;
//idsoft yfov = 2*atan((float)r_newrefdef.height/r_newrefdef.width)*180/M_PI;
qglMatrixMode(GL_PROJECTION);
qglLoadIdentity();
MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4, 4096);
qglCullFace(GL_FRONT);
qglMatrixMode(GL_MODELVIEW);
qglLoadIdentity();
qglRotatef(-90, 1, 0, 0); // put Z going up
qglRotatef(90, 0, 0, 1); // put Z going up
qglRotatef(-r_newrefdef.viewangles[2], 1, 0, 0);
qglRotatef(-r_newrefdef.viewangles[0], 0, 1, 0);
qglRotatef(-r_newrefdef.viewangles[1], 0, 0, 1);
qglTranslatef(-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
//idsoft if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled )
//idsoft qglTranslatef ( gl_state.camera_separation, 0, 0 );
qglGetFloatv(GL_MODELVIEW_MATRIX, @r_world_matrix);
//
// set drawing parms
//
if (gl_cull.value <> 0) then
qglEnable(GL_CULL_FACE)
else
qglDisable(GL_CULL_FACE);
qglDisable(GL_BLEND);
qglDisable(GL_ALPHA_TEST);
qglEnable(GL_DEPTH_TEST);
end;
{*
=============
R_Clear
=============
*}
procedure R_Clear;
{$IFDEF COMPILER6_UP}{$WRITEABLECONST ON}{$ENDIF}
const
trickframe: integer = 0;
{$IFDEF COMPILER6_UP}{$WRITEABLECONST OFF}{$ENDIF}
begin
if (gl_ztrick.value <> 0) then
begin
if (gl_clear_.value <> 0) then
qglClear(GL_COLOR_BUFFER_BIT);
Inc(trickframe);
if (trickframe and 1) <> 0 then
begin
gldepthmin := 0;
gldepthmax := 0.49999;
qglDepthFunc(GL_LEQUAL);
end
else
begin
gldepthmin := 1;
gldepthmax := 0.5;
qglDepthFunc(GL_GEQUAL);
end;
end
else
begin
if (gl_clear_.value <> 0) then
qglClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
else
qglClear(GL_DEPTH_BUFFER_BIT);
gldepthmin := 0;
gldepthmax := 1;
qglDepthFunc(GL_LEQUAL);
end;
qglDepthRange(gldepthmin, gldepthmax);
end;
procedure R_Flash;
begin
R_PolyBlend();
end;
{*
================
R_RenderView
r_newrefdef must be set before the first call
================
*}
procedure R_RenderView(fd: refdef_p);
begin
if (r_norefresh.value <> 0) then
Exit;
r_newrefdef := fd^;
if (r_worldmodel = nil) and ((r_newrefdef.rdflags and RDF_NOWORLDMODEL) = 0) then
ri.Sys_Error(ERR_DROP, 'R_RenderView: NULL worldmodel', []);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -