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

📄 gl_warp.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
// PLEASE, don't modify this file
// 81% complete

{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): gl_warp.c -- sky and water polygons                               }
{                                                                            }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru            }
{ Initial conversion on : 16-Jan-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ Copyright (C) 1997-2001 Id Software, Inc.                                  }
{                                                                            }
{ This program is free software; you can redistribute it and/or              }
{ modify it under the terms of the GNU General Public License                }
{ as published by the Free Software Foundation; either version 2             }
{ of the License, or (at your option) any later version.                     }
{                                                                            }
{ This program is distributed in the hope that it will be useful,            }
{ but WITHOUT ANY WARRANTY; without even the implied warranty of             }
{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       }
{                                                                            }
{ See the GNU General Public License for more details.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ Updated on :                                                               }
{ Updated by :                                                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{                                                                            }
{ x) warpsin.inc                                                             }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Do more tests                                                           }
{                                                                            }
{----------------------------------------------------------------------------}

// gl_warp.c -- sky and water polygons

unit gl_warp;

interface

uses q_shared, gl_model_h;

procedure GL_SubdivideSurface (fa : msurface_p); //for gl_model
procedure R_SetSky (name : PChar; rotate : float; axis : vec3_t); cdecl; //for gl_rmain

implementation
uses Ref, gl_local,     GL, qgl_win, gl_image;// Math_procedure Xxx(); overload;{$I OVERLOAD_need_remove.inc}

var
//extern	model_t	*loadmodel;
  loadmodel : model_p;

(*
char	skyname[MAX_QPATH];
float	skyrotate;
vec3_t	skyaxis;
image_t	*sky_images[6];

msurface_t	*warpface;*)
  skyname : array [0..MAX_QPATH-1] of char;
  skyrotate : float;
  skyaxis : vec3_t;
  sky_images : array [0..5] of image_p;

  warpface : msurface_p;

const
  SUBDIVIDE_SIZE = 64;
//id: #define	SUBDIVIDE_SIZE	1024

//void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
procedure BoundPoly (numverts : integer; verts : Pfloat; mins, maxs : vec3_t);
var
  i, j : integer;
//	float	*v;
  v : Pfloat;
begin
  mins[0] := 9999;
  mins[1] := mins[0];
  mins[2] := mins[0];
  maxs[0] := -9999;
  maxs[1] := maxs[0];
  maxs[2] := maxs[0];
  v := verts; 
  for i:=0 to numverts-1 do
    for j:=0 to 2 do
    begin
(*  			if (*v < mins[j])
    				mins[j] = *v;
    			if (*v > maxs[j])
    				maxs[j] = *v;*)
       if (v^ < mins[j]) then
         mins[j] := v^;
       if (v^ > maxs[j]) then
         maxs[j] := v^;
      Inc(v);
    end;
end; //procedure

//void SubdividePolygon (int numverts, float *verts)
//{Y} Recursion procedure
procedure SubdividePolygon (numverts : integer; verts : Pfloat); //verts : PFloatArray OR "array of float"
var
  i, j, k   : integer;
  mins,
  maxs      : vec3_t;
  m         : float;

//	float	*v;
	v : Pfloat;
_v : vec3_p;        

  front,
  back     : array [0..63] of vec3_t;
  f, b     : integer;
  dist     : array [0..63] of float;
  frac     : float;

//	glpoly_t	*poly;
  poly : glpoly_p;

  total    : vec3_t;
  s, t,
  total_s,
  total_t  : float;
begin
  if (numverts > 60) then
    ri.Sys_Error (ERR_DROP, 'numverts = %i', [numverts]);

  BoundPoly (numverts, verts, mins, maxs);

  for i:=0 to 2 do
  begin
    m := (mins[i] + maxs[i]) * 0.5;
    m := SUBDIVIDE_SIZE * Floor (m/SUBDIVIDE_SIZE + 0.5);
    if (maxs[i] - m < 8) then
      Continue;
    if (m - mins[i] < 8) then
      Continue;

    // cut it
{    v := verts + i;
    for (j=0 ; j<numverts ; j++, v+= 3)
      dist[j] = *v - m;}
    v := verts;
    Inc(v, i);
    for j:=0 to numverts-1 do
    begin
      dist[j] := v^ - m;
      Inc(v, 3);
    end;

    // wrap cases
    dist[j] := dist[0];
    Dec(v, i);
    VectorCopy (verts, v);

    f := 0;
    b := 0;
    v := pfloat(verts);
//{Y}    for (j=0 ; j<numverts ; j++, v+= 3)
    for j:=0 to numverts-1 do
    begin
      if (dist[j] >= 0) then
      begin
        VectorCopy (v, front[f]);
        Inc(f);
      end;
      if (dist[j] <= 0) then
      begin
        VectorCopy (v, back[b]);
        Inc(b);
      end;
      if (dist[j] = 0) OR (dist[j+1] = 0) then
        Continue;
      if ( (dist[j] > 0) <> (dist[j+1] > 0) ) then
      begin
        // clip point
        frac := dist[j] / (dist[j] - dist[j+1]);
        for k:=0 to 2 do
        begin
//Y             front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
//          back[b][k]  := v[k] + frac*(v[3+k] - v[k]);
_v := vec3_p(v);
back[b][k]  := _v[k] + frac*(_v[3+k] - _v[k]);
          front[f][k] := back[b][k];
        end;
        Inc(f);
        Inc(b);
      end;

      Inc (v, 3);
    end;//for???

    SubdividePolygon (f, @front[0]); //Y: @
    SubdividePolygon (b, @back[0]); //Y: @
//    return; //??? - ???
    Exit; //{Y} Recursion procedure
  end; //for i

  // add a point in the center to help keep warp valid
//Y  poly := Hunk_Alloc (sizeof(glpoly_t) + ((numverts-4)+2) * VERTEXSIZE*sizeof(float));
  poly.next := warpface.polys;
  warpface.polys := poly;
  poly.numverts := numverts+2;
  VectorClear (total);
  total_s := 0;
  total_t := 0;
{Y}  for i:=0 to numverts-1 do // ; i++, verts+= 3)
  begin
    VectorCopy (verts, @poly.verts[i+1]);
    s := DotProduct (verts, @warpface.texinfo.vecs[0]);
    t := DotProduct (verts, @warpface.texinfo.vecs[1]);

    total_s := total_s +s;
    total_t := total_t +t;
    VectorAdd (total, verts, total);

    poly.verts[i+1][3] := s;
    poly.verts[i+1][4] := t;

  end;//for??? i

  VectorScale (total, (1.0/numverts), @poly.verts[0]);
  poly.verts[0][3] := total_s/numverts;
  poly.verts[0][4] := total_t/numverts;

  // copy first vertex to last
//  memcpy (poly.verts[i+1], poly.verts[1], sizeof(poly.verts[0]));
  poly.verts[i+1] := poly.verts[1];
end;//procedure

{*
================
GL_SubdivideSurface

Breaks a polygon up along axial 64 unit
boundaries so that turbulent and sky warps
can be done reasonably.
================
*}
//void GL_SubdivideSurface (msurface_t *fa)
procedure GL_SubdivideSurface (fa : msurface_p); //for gl_model
var
  verts    : array [0..63] of vec3_t;
  numverts,
  i,
  lindex   : integer;

//	float		*vec;
vec : vec3_t;

begin
  warpface := fa;
  //
  // convert edges back to a normal polygon
  //
  numverts := 0;
  for i:=0 to fa.numedges-1 do
  begin
    lindex := loadmodel.surfedges[fa.firstedge + i];

    if (lindex > 0)
    then vec := loadmodel.vertexes[loadmodel.edges[lindex].v[0]].position
    else vec := loadmodel.vertexes[loadmodel.edges[-lindex].v[1]].position;
    VectorCopy (vec, verts[numverts]);
    Inc(numverts);
  end;

  SubdividePolygon (numverts, @verts[0]);  //Y
end;//procedure

var
  // speed up sin calculations - Ed
  r_turbsin : array [0..32*8-1] of float =
    (
    {$I ..\..\Source\warpsin.inc}
    );

const
  TURBSCALE = 256.0 /(2 * M_PI);

{*
=============
EmitWaterPolys

Does a water warp on the pre-fragmented glpoly_t chain
=============
*}
//void EmitWaterPolys (msurface_t *fa)
procedure EmitWaterPolys (fa : msurface_p);
var
//	glpoly_t	*p, *bp;
  bp, p : glpoly_p;
  	  
//	float		*v;

  i       : integer;
  s, t,
  os, ot,
  scroll,
  rdt  : float;
begin
  rdt := r_newrefdef.time;

//{Y}  if (fa->texinfo->flags & SURF_FLOWING)
  if ((fa.texinfo.flags AND SURF_FLOWING) <> 0)
//  then scroll := -64 * ( (r_newrefdef.time*0.5) - (int)(r_newrefdef.time*0.5) )
  then scroll := -64 * Frac(r_newrefdef.time*0.5)  //Y: optimize
  else scroll := 0;

//Y:  for (bp=fa->polys ; bp ; bp=bp->next)
  bp := fa.polys;
  while (bp<>Nil) do
  begin
          p := bp;

          qglBegin (GL_TRIANGLE_FAN);
(*Y            {Y}for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
            begin
                  os := v[3];
                  ot := v[4];

#if !id386
                  s = os + r_turbsin[(int)((ot*0.125+r_newrefdef.time) * TURBSCALE) & 255];
#else
                  s = os + r_turbsin[Q_ftol( ((ot*0.125+rdt) * TURBSCALE) ) & 255];
#endif
                  s := s +scroll;
                  s := s *(1.0/64);
                  //optimize code s := (s +scroll) *invert64;

#if !id386
                  t = ot + r_turbsin[(int)((os*0.125+rdt) * TURBSCALE) & 255];
#else
                  t = ot + r_turbsin[Q_ftol( ((os*0.125+rdt) * TURBSCALE) ) & 255];
#endif
                  t := t *(1.0/64);
                  //optimize code t := t *invert64;

                  qglTexCoord2f (s, t);
                  qglVertex3fv (v);

            end;//for???*)
          qglEnd ();

    bp := bp.next;
  end;//for???

end;//procedure

const
  skyclip : array [0..5] of vec3_t =
    ( (1,1,0),
      (1,-1,0),
      (0,-1,1),
      (0,1,1),
      (1,0,1),
      (-1,0,1) );
var
  c_sky : integer;

const
  // 1 = s, 2 = t, 3 = 2048
  st_to_vec : array [0..5, 0..2] of integer =
    ( (3,-1,2),
      (-3,1,2),

      (1,3,2),
      (-1,-3,2),

      (-2,-1,3),  // 0 degrees yaw, look straight up
      (2,-1,-3)	  // look straight down

//	{-1,2,3},
//	{1,2,-3}
    );

  // s = [0]/[2], t = [1]/[2]
  vec_to_st : array [0..5, 0..2] of integer =
    ( (-2,3,1),
      (2,3,-1),

      (1,3,2),
      (-1,3,-2),

      (-2,-1,3),
      (-2,1,-3)

//	{-1,2,3},
//	{1,2,-3}
    );

var
  skymins, skymaxs : array [0..1, 0..5] of float;
  sky_min, sky_max : float;

procedure DrawSkyPolygon (nump : integer; vecs : vec3_t);
var
  i, j,
  axis     : integer;

⌨️ 快捷键说明

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