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

📄 gl_rsurf.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    Exit;
  end; //if

// node is just a decision point, so go down the apropriate sides

// find which side of the node we are on
  plane := node^.plane;

  case plane^._type of
    PLANE_X: dot := modelorg[0] - plane.dist;
    PLANE_Y: dot := modelorg[1] - plane.dist;
    PLANE_Z: dot := modelorg[2] - plane.dist;
  else
    dot := DotProduct(modelorg, plane^.normal) - plane^.dist;
  end;

  if (dot >= 0) then
  begin
    side := 0;
    sidebit := 0;
  end
  else
  begin
    side := 1;
    sidebit := SURF_PLANEBACK;
  end;

// recurse down the children, front side first
  R_RecursiveWorldNode(node^.children[side]);

  // draw stuff
  c := node^.numsurfaces;
  surf := @r_worldmodel^.surfaces^[node^.firstsurface];
  while (c <> 0) do
  begin
    if (surf.visframe <> r_framecount) then
      goto Continue_;

    if ((surf^.flags and SURF_PLANEBACK) <> sidebit) then
      goto Continue_; // wrong side

    if (surf^.texinfo^.flags and SURF_SKY) <> 0 then
    begin
      // just adds to visible sky bounds
      R_AddSkySurface(surf);
    end
    else
      if (surf^.texinfo^.flags and (SURF_TRANS33 or SURF_TRANS66) <> 0) then
      begin
        // add to the translucent chain
        surf^.texturechain := r_alpha_surfaces;
        r_alpha_surfaces := surf;
      end
      else
      begin
        if (Assigned(qglMTexCoord2fSGIS) and ((surf^.flags and SURF_DRAWTURB) = 0)) then
          GL_RenderLightmappedPoly(surf)
        else
        begin
          // the polygon is visible, so add it to the texture
          // sorted chain
          // FIXME: this is a hack for animation
          image := R_TextureAnimation(surf^.texinfo);
          surf^.texturechain := image^.texturechain;
          image^.texturechain := surf;
        end;
      end;
    Continue_:
    Dec(c);
    Inc(surf);
  end;

  // recurse down the back side

  if side = 0 then
    notside_ := 1
  else
    notside_ := 0;
  R_RecursiveWorldNode(node.children[notside_]);
(*Id Software /*
 for ( ; c ; c--, surf++)
 {
  if (surf->visframe != r_framecount)
   continue;

  if ( (surf->flags & SURF_PLANEBACK) != sidebit )
   continue;		// wrong side

  if (surf->texinfo->flags & SURF_SKY)
  {	// just adds to visible sky bounds
   R_AddSkySurface (surf);
  }
  else if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
  {	// add to the translucent chain
//			surf->texturechain = alpha_surfaces;
//			alpha_surfaces = surf;
  }
  else
  {
   if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) )
   {
    GL_RenderLightmappedPoly( surf );
   }
   else
   {
    // the polygon is visible, so add it to the texture
    // sorted chain
    // FIXME: this is a hack for animation
    image = R_TextureAnimation (surf->texinfo);
    surf->texturechain = image->texturechain;
    image->texturechain = surf;
   }
  }
 }
*/*)
end; //procedure

{*
=============
R_DrawWorld
=============
*}
procedure R_DrawWorld; //for gl_rmain
var
  ent: entity_t;
begin
  if (r_drawworld_.value = 0) then
    Exit;

  if (r_newrefdef.rdflags and RDF_NOWORLDMODEL) <> 0 then
    Exit;

  currentmodel := r_worldmodel;

  VectorCopy(vec3_t(r_newrefdef.vieworg), modelorg);

  // auto cycle the world frame for texture animation
  memset(@ent, 0, sizeof(ent));
  ent.frame := Trunc(r_newrefdef.time * 2);
  currententity := @ent;

  gl_state.currenttextures[0] := -1;
  gl_state.currenttextures[1] := -1;

  qglColor3f(1, 1, 1);
  memset(@gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
  R_ClearSkyBox();

  if Assigned(qglMTexCoord2fSGIS) then
  begin
    GL_EnableMultitexture(true);

    GL_SelectTexture(GL_TEXTURE0);
    GL_TexEnv(GL_REPLACE);
    GL_SelectTexture(GL_TEXTURE1);

    if (gl_lightmap.value <> 0) then
      GL_TexEnv(GL_REPLACE)
    else
      GL_TexEnv(GL_MODULATE);

    R_RecursiveWorldNode(r_worldmodel^.nodes);

    GL_EnableMultitexture(false);
  end
  else
    R_RecursiveWorldNode(r_worldmodel^.nodes);

  {*
  ** theoretically nothing should happen in the next two functions
  ** if multitexture is enabled
  *}
  DrawTextureChains();
  R_BlendLightmaps();

  R_DrawSkyBox();

  R_DrawTriangleOutlines();
end; //procedure

{*
===============
R_MarkLeaves

Mark the leaves and nodes that are in the PVS for the current
cluster
===============
*}
procedure R_MarkLeaves; //for gl_rmain
var
  vis: PByte;
  fatvis: array[0..MAX_MAP_LEAFS div 8 - 1] of byte;

  node: mnode_p;
  i, c,
    cluster: integer;
  leaf: mleaf_p;
label
  continue_;
begin
  if (r_oldviewcluster = r_viewcluster) and (r_oldviewcluster2 = r_viewcluster2) and
    (r_novis.value = 0) and (r_viewcluster <> -1) then
    Exit;

  // development aid to let you run around and see exactly where
  // the pvs ends
  if (gl_lockpvs^.value <> 0) then
    Exit;

  Inc(r_visframecount);
  r_oldviewcluster := r_viewcluster;
  r_oldviewcluster2 := r_viewcluster2;

  if (r_novis^.value <> 0) or (r_viewcluster = -1) or (r_worldmodel.vis = nil) then
  begin
    // mark everything
    for i := 0 to r_worldmodel.numleafs - 1 do
      mLeaf_arrp(r_worldmodel.leafs)[i].visframe := r_visframecount;
    for i := 0 to r_worldmodel.numnodes - 1 do
      mNode_arrp(r_worldmodel.nodes)[i].visframe := r_visframecount;
    Exit;
  end;

  vis := Mod_ClusterPVS(r_viewcluster, r_worldmodel);
  // may have to combine two clusters because of solid water boundaries
  if (r_viewcluster2 <> r_viewcluster) then
  begin
    memcpy(@fatvis, vis, (r_worldmodel.numleafs + 7) div 8);
    vis := Mod_ClusterPVS(r_viewcluster2, r_worldmodel);
    c := (r_worldmodel.numleafs + 31) div 32;
    for i := 0 to c - 1 do
      PIntegerArray(@fatvis)^[i] := PIntegerArray(@fatvis)^[i] or PIntegerArray(vis)^[i];
    vis := @fatvis;
  end;

  leaf := r_worldmodel^.leafs;
  for i := 0 to r_worldmodel^.numleafs - 1 do
  begin
    cluster := leaf^.cluster;
    if (cluster = -1) then
      goto continue_;
    if (PByteArray(vis)^[cluster shr 3] and (1 shl (cluster and 7))) <> 0 then
    begin
      node := mnode_p(leaf);
      repeat
        if (node.visframe = r_visframecount) then
          Break;
        node.visframe := r_visframecount;
        node := node.parent;
      until node = nil;
    end;
    continue_:
    Inc(leaf);
  end;

(*
 for (i=0 ; i<r_worldmodel->vis->numclusters ; i++)
 {
  if (vis[i>>3] & (1<<(i&7)))
  {
   node = (mnode_t * )&r_worldmodel->leafs[i];	// FIXME: cluster
   do
   {
    if (node->visframe == r_visframecount)
     break;
    node->visframe = r_visframecount;
    node = node->parent;
   } while (node);
  }
 }
*)
end; //procedure



{*
=============================================================================

  LIGHTMAP ALLOCATION

=============================================================================
*}

procedure {static}  LM_InitBlock;
begin
  FillChar(gl_lms.allocated, sizeof(gl_lms.allocated), 0);
end; //procedure

procedure {static}  LM_UploadBlock(dynamic_: qboolean);
var
  texture, i,
    height: integer;
begin
  height := 0;

  if dynamic_ then
    texture := 0
  else
    texture := gl_lms.current_lightmap_texture;

  GL_Bind(gl_state.lightmap_textures + texture);
  qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  if dynamic_ then
  begin
    for i := 0 to BLOCK_WIDTH - 1 do
      if (gl_lms.allocated[i] > height) then
        height := gl_lms.allocated[i];

    qglTexSubImage2D(GL_TEXTURE_2D,
      0,
      0, 0,
      BLOCK_WIDTH, height,
      GL_LIGHTMAP_FORMAT,
      GL_UNSIGNED_BYTE,
      @gl_lms.lightmap_buffer);
  end
  else
  begin
    qglTexImage2D(GL_TEXTURE_2D,
      0,
      gl_lms.internal_format,
      BLOCK_WIDTH, BLOCK_HEIGHT,
      0,
      GL_LIGHTMAP_FORMAT,
      GL_UNSIGNED_BYTE,
      @gl_lms.lightmap_buffer);
    Inc(gl_lms.current_lightmap_texture);
    if (gl_lms.current_lightmap_texture = MAX_LIGHTMAPS) then
      ri.Sys_Error(ERR_DROP, 'LM_UploadBlock() - MAX_LIGHTMAPS exceeded'#10, []);
  end;
end; //procedure


// returns a texture number and the position inside it
function {static}  LM_AllocBlock(w, h: integer; var x, y: integer): qboolean;
var
  i, j,
    best, best2: integer;
begin
  best := BLOCK_HEIGHT;

  for i := 0 to BLOCK_WIDTH - w - 1 do
  begin
    best2 := 0;

    j := 0;
    while (j < w) do
    begin
      if (gl_lms.allocated[i + j] >= best) then
        Break;
      if (gl_lms.allocated[i + j] > best2) then
        best2 := gl_lms.allocated[i + j];
      inc(j);
    end;
    if (j = w) then
    begin
      // this is a valid spot
      x := i;
      best := best2;
      y := best;
    end;
  end; //for

  if (best + h > BLOCK_HEIGHT) then
  begin
    Result := false;
    Exit;
  end;

  for i := 0 to w - 1 do
    gl_lms.allocated[{*} x + i] := best + h;

  Result := true;
end; //function

{*
================
GL_BuildPolygonFromSurface
================
*}
procedure GL_BuildPolygonFromSurface(fa: msurface_p);
var
  i, lindex,
  lnumverts,
  vertpage: integer;
  pedges,
  r_pedge: medge_p;
  vec: vec3_t;

  s, t: Single;
  poly: glpoly_p;
  total: vec3_t;
begin
  // reconstruct the polygon
  pedges := medge_p(currentmodel^.edges);
  lnumverts := fa^.numedges;
  vertpage := 0;

  VectorClear(total);
  //
  // draw texture
  //
  poly := Hunk_Alloc(sizeof(glpoly_t) + (lnumverts - 4) * VERTEXSIZE * sizeof(Single));
  poly^.next := fa^.polys;
  poly^.flags := fa^.flags;
  fa^.polys := poly;
  poly^.numverts := lnumverts;

  for i := 0 to lnumverts - 1 do
  begin
    lindex := PIntegerArray(currentmodel^.surfedges)^[fa^.firstedge + i];

    if (lindex > 0) then
    begin
      r_pedge := @mEdge_arrp(pedges)^[lindex];
      vec := currentmodel^.vertexes[r_pedge^.v[0]].position;
    end
    else
    begin
      r_pedge := @mEdge_arrp(pedges)^[-lindex];
      vec := currentmodel^.vertexes[r_pedge^.v[1]].position;
    end;
    s := DotProduct(vec, vec3_p(@fa^.texinfo^.vecs[0])^) + fa^.texinfo^.vecs[0][3];
    s := s / fa^.texinfo^.image^.width;

    t := DotProduct(vec, vec3_p(@fa^.texinfo^.vecs[1])^) + fa^.texinfo^.vecs[1][3];
    t := t / fa^.texinfo^.image^.height;

    VectorAdd(total, vec, total);
    VectorCopy(vec, vec3_t(vec3_p(@poly^.verts[i])^));
    poly.verts[i][3] := s;
    poly.verts[i][4] := t;

    //
    // lightmap texture coordinates
    //
    s := DotProduct(vec, vec3_p(@fa^.texinfo^.vecs[0])^) + fa^.texinfo^.vecs[0][3];
    s := s - fa^.texturemins[0];
    s := s + fa^.light_s * 16;
    s := s + 8;
    s := s / (BLOCK_WIDTH * 16); //fa->texinfo->texture->width;

    t := DotProduct(vec, vec3_p(@fa^.texinfo^.vecs[1])^) + fa^.texinfo^.vecs[1][3];
    t := t - fa^.texturemins[1];
    t := t + fa^.light_t * 16;
    t := t + 8;
    t := t / (BLOCK_HEIGHT * 16); //fa->texinfo->texture->height;

    poly^.verts[i][5] := s;
    poly^.verts[i][6] := t;
  end; //for

  poly^.numverts := lnumverts;
end; //procedure

{*
========================
GL_CreateSurfaceLightmap
========================
*}
procedure GL_CreateSurfaceLightmap(surf: msurface_p);
var
  smax, tmax: integer;
  base: PByte;
begin
  if (surf.flags and (SURF_DRAWSKY or SURF_DRAWTURB) <> 0) then
    Exit;

  smax := (surf.extents[0] shr 4) + 1;
  tmax := (surf.extents[1] shr 4) + 1;

  if (not LM_AllocBlock(smax, tmax, surf^.light_s, surf^.light_t)) then
  begin
    LM_UploadBlock(false);
    LM_InitBlock();
    if (not LM_AllocBlock(smax, tmax, surf^.light_s, surf^.light_t)) then
      ri.Sys_Error(ERR_FATAL, 'Consecutive calls to LM_AllocBlock(%d,%d) failed'#10, [smax, tmax]);
  end;

  surf^.lightmaptexturenum := gl_lms.current_lightmap_texture;

  base := @gl_lms.lightmap_buffer;
  Inc(base, (surf^.light_t * BLOCK_WIDTH + surf^.light_s) * LIGHTMAP_BYTES);

  R_SetCacheState(surf);
  R_BuildLightMap(surf, PByteArray(base), BLOCK_WIDTH * LIGHTMAP_BYTES);
end; //procedure

{*
==================
GL_BeginBuildingLightmaps
==================
*}
var
  lightstyles: array[0..MAX_LIGHTSTYLES - 1] of lightstyle_t;

procedure GL_BeginBuildingLightmaps(m: model_p); //for gl_model
//	static lightstyle_t	lightstyles[MAX_LIGHTSTYLES];
var
  i: integer;
  dummy: array[0..128 * 128 - 1] of Cardinal;
begin
  memset(@gl_lms.allocated, 0, sizeof(gl_lms.allocated));

  r_framecount := 1; // no dlightcache

  GL_EnableMultitexture(true);
  GL_SelectTexture(GL_TEXTURE1);

  {*
  ** setup the base lightstyles so the lightmaps won't have to be regenerated
  ** the first time they're seen
  *}
  for i := 0 to MAX_LIGHTSTYLES - 1 do
  begin
    lightstyles[i].rgb[0] := 1;
    lightstyles[i].rgb[1] := 1;
    lightstyles[i].rgb[2] := 1;
    lightstyles[i].white := 3;
  end;
  r_newrefdef.lightstyles := @lightstyles;

  if (gl_state.lightmap_textures = 0) then
  begin
    gl_state.lightmap_textures := TEXNUM_LIGHTMAPS;
//idsoft		gl_state.lightmap_textures	= gl_state.texture_extension_number;
//idsoft		gl_state.texture_extension_number = gl_state.lightmap_textures + MAX_LIGHTMAPS;
  end;

  gl_lms.current_lightmap_texture := 1;

  {*
  ** if mono lightmaps are enabled and we want to use alpha
  ** blending (a,1-a) then we're likely running on a 3DLabs
  ** Permedia2.  In a perfect world we'd use a GL_ALPHA lightmap
  ** in order to conserve space and maximize bandwidth, however
  ** this isn't a perfect world.
  **
  ** So we have to use alpha lightmaps, but stored in GL_RGBA format,
  ** which means we only get 1/16th the color resolution we should when
  ** using alpha lightmaps.  If we find another board that supports
  ** only alpha lightmaps but that can at least support the GL_ALPHA
  ** format then we should change this code to use real alpha maps.
  *}
//  if ( toupper( gl_monolightmap.string[0] ) == 'A' )
  if UpCase(gl_monolightmap.string_[0]) = 'A' then
  begin
    gl_lms.internal_format := gl_tex_alpha_format;
  end
  {*
  ** try to do hacked colored lighting with a blended texture
  *}
  else
    if UpCase(gl_monolightmap.string_[0]) = 'C' then
      gl_lms.internal_format := gl_tex_alpha_format
    else
      if UpCase(gl_monolightmap.string_[0]) = 'I' then
        gl_lms.internal_format := GL_INTENSITY8
      else
        if UpCase(gl_monolightmap.string_[0]) = 'L' then
          gl_lms.internal_format := GL_LUMINANCE8
        else
          gl_lms.internal_format := gl_tex_solid_format;

  {*
  ** initialize the dynamic lightmap texture
  *}
  GL_Bind(gl_state.lightmap_textures + 0);
  qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  qglTexImage2D(GL_TEXTURE_2D,
    0,
    gl_lms.internal_format,
    BLOCK_WIDTH, BLOCK_HEIGHT,
    0,
    GL_LIGHTMAP_FORMAT,
    GL_UNSIGNED_BYTE,
    @dummy);
end; //procedure

{*
=======================
GL_EndBuildingLightmaps
=======================
*}
procedure GL_EndBuildingLightmaps; //for gl_model
begin
  LM_UploadBlock(false);
  GL_EnableMultitexture(false);
end; //procedure

// End of file
end.

⌨️ 快捷键说明

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