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

📄 gl_warp.pas

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