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

📄 gl_light.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  light := 0;
  dl := r_newrefdef.dlights;
  for lnum := 0 to r_newrefdef.num_dlights - 1 do
  begin
    VectorSubtract(vec3_p(@currententity^.origin)^, dl^.origin, dist);
    add := dl^.intensity - (VectorLength(dist));
    add := add * (1 / 256);
    if (add > 0) then
      VectorMA(color, add, dl^.color, color);

    Inc(dl);
  end;

  VectorScale(color, gl_modulate_^.value, color);
end;


(*
===============
R_AddDynamicLights
===============
*)
procedure R_AddDynamicLights(surf: msurface_p);
var
  lnum,
    sd,
    td: Integer;
  fdist,
    frad,
    fminlight: Single;
  impact,
    local: vec3_t;
  s, t, i, smax,
    tmax: Integer;
  tex: mtexinfo_p;
  dl: dlight_p;
  pfBL: PSingleArray;
  fsacc,
    ftacc: Single;
begin
  smax := (surf^.extents[0] shr 4) + 1;
  tmax := (surf^.extents[1] shr 4) + 1;
  tex := surf^.texinfo;
  for lnum := 0 to r_newrefdef.num_dlights - 1 do
  begin
    if ((surf^.dlightbits and (1 shl lnum)) = 0) then
      continue; // not lit by this light

    dl := @dlight_arrp(r_newrefdef.dlights)^[lnum];
    frad := dl^.intensity;
    fdist := DotProduct(dl^.origin, surf^.plane^.normal) - surf^.plane^.dist;
    frad := frad - fabs(fdist);
     // rad is now the highest intensity on the plane

    fminlight := DLIGHT_CUTOFF; // FIXME: make configurable?

    if (frad < fminlight) then
      continue;
    fminlight := frad - fminlight;

    for i := 0 to 2 do
    begin
      impact[i] := dl^.origin[i] - surf^.plane^.normal[i] * fdist;
    end;

    local[0] := trunc(DotProduct(impact, vec3_p(@tex^.vecs[0])^) + tex^.vecs[0][3] - surf^.texturemins[0]);
    local[1] := trunc(DotProduct(impact, vec3_p(@tex^.vecs[1])^) + tex^.vecs[1][3] - surf^.texturemins[1]);

    pfBL := @s_blocklights;
    ftacc := 0;
    for t := 0 to tmax - 1 do
    begin
      td := trunc(local[1] - ftacc);
      if (td < 0) then
        td := -td;
      fsacc := 0;
      for s := 0 to smax - 1 do
      begin
        sd := Q_ftol(local[0] - fsacc);
        if (sd < 0) then
          sd := -sd;
        if (sd > td) then
          fdist := sd + (td shr 1)
        else
          fdist := td + (sd shr 1);
        if (fdist < fminlight) then
        begin
          pfBL[0] := pfBL[0] + (frad - fdist) * dl^.color[0];
          pfBL[1] := pfBL[1] + (frad - fdist) * dl^.color[1];
          pfBL[2] := pfBL[2] + (frad - fdist) * dl^.color[2];
        end;
        fsacc := fsacc + 16;
        pfBL := Pointer(Cardinal(pfBL) + 3 * SizeOf(Single));
      end;
      ftacc := ftacc + 16;
    end;
  end;
end;


(*
** R_SetCacheState
*)
procedure R_SetCacheState(surf: msurface_p);
var
  maps: integer;
begin
  maps := 0;
  while (maps < MAXLIGHTMAPS) and (surf^.styles[maps] <> 255) do
  begin
    surf^.cached_light[maps] := r_newrefdef.lightstyles[surf^.styles[maps]].white;
    inc(maps);
  end;
end;


(*
===============
R_BuildLightMap

Combine and scale multiple lightmaps into the floating format in blocklights
===============
*)
procedure R_BuildLightMap(surf: msurface_p; dest: PByteArray; stride: integer);
var
  smax, tmax: integer;
  r, g, b, a, max: integer;
  i, j, size: integer;
  lightmap: PByteArray;
  scale: array[0..3] of Single;
  nummaps: integer;
  bl: PSingleArray;
  style: lightstyle_p;
  monolightmap: integer;
  maps: integer;
  t: Single;
label
  Store;
begin
  if (surf^.TexInfo^.Flags and (SURF_SKY or SURF_TRANS33 or SURF_TRANS66 or SURF_WARP)) <> 0 then
    ri.Sys_Error(ERR_DROP, 'R_BuildLightMap called for non-lit surface');

  smax := (surf^.extents[0] shr 4) + 1;
  tmax := (surf^.extents[1] shr 4) + 1;
  size := smax * tmax;
  if (size > (sizeof(s_blocklights) shr 4)) then
    ri.Sys_Error(ERR_DROP, 'Bad s_blocklights size');

 // set to full bright if no light data
  if (surf^.samples = nil) then
  begin
    for i := 0 to (size * 3) - 1 do
      s_blocklights[i] := 255;

    maps := 0;
    while (maps < MAXLIGHTMAPS) and (surf^.styles[maps] <> 255) do
    begin
      style := @r_newrefdef.lightstyles[surf^.styles[maps]];
      Inc(maps);
    end;
    goto store;
  end;

  // count the # of maps
  nummaps := 0;
  while (nummaps < MAXLIGHTMAPS) and (surf^.styles[nummaps] <> 255) do
    Inc(nummaps);

  lightmap := Pointer(surf^.samples);

  // add all the lightmaps
  if (nummaps = 1) then
  begin
    maps := 0;
    while (maps < MAXLIGHTMAPS) and (surf^.styles[maps] <> 255) do
    begin
      bl := @s_blocklights;
      for i := 0 to 2 do
        scale[i] := gl_modulate_^.value * r_newrefdef.lightstyles[surf^.styles[maps]].rgb[i];
      if (scale[0] = 1) and
        (scale[1] = 1) and
        (scale[2] = 1) then
      begin
        for i := 0 to size - 1 do
        begin
          bl[0] := lightmap[i * 3 + 0];
          bl[1] := lightmap[i * 3 + 1];
          bl[2] := lightmap[i * 3 + 2];
          inc(PSingle(bl), 3);
        end;
      end
      else
      begin
        for i := 0 to size - 1 do
        begin
          bl[0] := lightmap[i * 3 + 0] * scale[0];
          bl[1] := lightmap[i * 3 + 1] * scale[1];
          bl[2] := lightmap[i * 3 + 2] * scale[2];
          inc(pSingle(bl), 3);
        end;
      end;
      inc(pByte(lightmap), size * 3); // skip to next lightmap
      Inc(maps);
    end;
  end
  else
  begin
    memset(@s_blocklights, 0, sizeof(s_blocklights[0]) * size * 3);
    maps := 0;
    while (maps < MAXLIGHTMAPS) and (surf^.styles[maps] <> 255) do
    begin
      bl := @s_blocklights;
      for i := 0 to 2 do
        scale[i] := gl_modulate_^.value * r_newrefdef.lightstyles[surf^.styles[maps]].rgb[i];

      if (scale[0] = 1) and
        (scale[1] = 1) and
        (scale[2] = 1) then
      begin
        for i := 0 to size - 1 do
        begin
          bl[0] := lightmap[i * 3 + 0];
          bl[1] := lightmap[i * 3 + 1];
          bl[2] := lightmap[i * 3 + 2];
          inc(pSingle(bl), 3);
        end;
      end
      else
      begin
        for i := 0 to size - 1 do
        begin
          bl[0] := lightmap[i * 3 + 0] * scale[0];
          bl[1] := lightmap[i * 3 + 1] * scale[1];
          bl[2] := lightmap[i * 3 + 2] * scale[2];
          inc(pSingle(bl), 3);
        end;
      end;
      inc(PByte(lightmap), size * 3); // skip to next lightmap
      Inc(maps);
    end;
  end;
  // add all the dynamic lights
  if (surf^.dlightframe = r_framecount) then
    R_AddDynamicLights(surf);

  // put into texture format
  Store: // Label

  stride := stride - (smax shl 2);
  bl := @s_blocklights;

  monolightmap := Byte(gl_monolightmap^.string_[0]);
  if (monolightmap = Byte('0')) then
  begin
    for i := 0 to tmax - 1 do
    begin
      for j := 0 to smax - 1 do
      begin
        r := Q_ftol(bl[0]);
        g := Q_ftol(bl[1]);
        b := Q_ftol(bl[2]);

        // catch negative lights
        if (r < 0) then
          r := 0;
        if (g < 0) then
          g := 0;
        if (b < 0) then
          b := 0;
        (*
        ** determine the brightest of the three color components
        *)
        if (r > g) then
          max := r
        else
          max := g;
        if (b > max) then
          max := b;
        (*
        ** alpha is ONLY used for the mono lightmap case.  For this reason
        ** we set it to the brightest of the color components so that
        ** things don't get too dim.
        *)

        a := max;

        (*
        ** rescale all the color components if the intensity of the greatest
        ** channel exceeds 1.0
        *)
        if (max > 255) then
        begin
          t := 255 / max;

          r := Trunc(r * t);
          g := Trunc(g * t);
          b := Trunc(b * t);
          a := Trunc(a * t);
        end;
        dest[0] := r;
        dest[1] := g;
        dest[2] := b;
        dest[3] := a;

        inc(pSingle(bl), 3);
        inc(PByte(dest), 4); //dest :=dest + 4;
      end;
      inc(PByte(dest), stride); // dest :=dest + stride;
    end
  end
  else
  begin
    for i := 0 to tmax - 1 do
    begin
      for j := 0 to smax - 1 do
      begin
        r := Q_ftol(bl[0]);
        g := Q_ftol(bl[1]);
        b := Q_ftol(bl[2]);

        // catch negative lights
        if (r < 0) then
          r := 0;
        if (g < 0) then
          g := 0;
        if (b < 0) then
          b := 0;
        (*/*
        //** determine the brightest of the three color components
        //*/*)
        if (r > g) then
          max := r
        else
          max := g;
        if (b > max) then
          max := b;
        (*
        ** alpha is ONLY used for the mono lightmap case.  For this reason
        ** we set it to the brightest of the color components so that
        ** things don't get too dim.
        *)

        a := max;

        (*
        ** rescale all the color components if the intensity of the greatest
        ** channel exceeds 1.0
        *)
        if (max > 255) then
        begin
          t := 255 / max;

          r := trunc(r * t);
          g := trunc(g * t);
          b := trunc(b * t);
          a := trunc(a * t);
        end;
        (*
        ** So if we are doing alpha lightmaps we need to set the R, G, and B
        ** components to 0 and we need to set alpha to 1-alpha.
        *)
        case Char(monolightmap) of
          'L',
            'I':
            begin
              r := a;
              g := 0;
              b := 0;
            end;
          'C':
            begin
              // try faking colored lighting
              a := Trunc(255 - ((r + g + b) / 3));
              r := Trunc(r * (a / 255));
              g := Trunc(g * (a / 255));
              b := Trunc(b * (a / 255));
            end;
        else
          //'A':
          begin
            r := 0;
            g := 0;
            b := 0;
            a := 255 - a;
          end;
        end;
        dest[0] := r;
        dest[1] := g;
        dest[2] := b;
        dest[3] := a;

        //bl :=bl + 3;
        inc(PSingle(bl), 3);

        inc(PByte(dest), 4); // dest :=dest + 4;
      end;
    end;
    inc(PByte(dest), stride); // dest := dest + stride ;
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -