⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gl_rmain.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
      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 + -