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

📄 gl_light.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
// 90 % 
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): gl_light.c                                                        }
{                                                                            }
{ Initial conversion by : Lars Middendorf (lmid@gmx.de)                      }
{ Initial conversion on : 24-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 : 27/07/02                                                      }
{ Updated by : Fabrizio Rossini rossini.f@libero.it                          }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ Unit STILL NOT COMPILE !!!!                                                }
{ Check the unit for Conversion errors                                       }
{----------------------------------------------------------------------------}
unit gl_light;

interface
uses SysUtils,
     OpenGL,
     q_shared ,CPas, ref , qgl_h , gl_model_h , gl_local;

type

pointcolor =vec3_t ;
lightplane =cplane_p ; // used as shadow plane
lightspot = vec3_t ;
					 
var
 r_dlightframecount:integer;
s_blocklights :array [0..(34*34*3)-1] of single;

const
 DLIGHT_CUTOFF	        =64;

{
=============================================================================

DYNAMIC LIGHTS BLEND RENDERING

=============================================================================
}


procedure R_RenderDlight(light:dlight_p);
procedure R_RenderDlights ;
procedure R_MarkLights (light:dlight_p; bit :integer ;node :mnode_p);
procedure R_PushDlights ;
function  RecursiveLightPoint (node :mnode_p; start,_end :vec3_t):integer;
procedure R_LightPoint (p :vec3_t ;color :vec3_t);
procedure R_AddDynamicLights (surf :msurface_p);
procedure R_SetCacheState (surf :msurface_p);
procedure R_BuildLightMap (surf :msurface_p ;dest :Array of Byte{PByte} ;stride :integer);


implementation

procedure R_RenderDlight(light:dlight_p);
var
i,j:integer;
a:single;
v:vec3_t;
rad:single;
begin
rad:= light.intensity * 0.35;
VectorSubtract(light.origin, r_origin, v);

{$IFDEF 0}
	// FIXME?
        if VectorLength(v) < rad then
        begin
		// view is inside the dlight
		V_AddBlend(light.color[0],light.color[1],light.color[2],light.intensity * 0.0003, v_blend);
		exit;
        end;
{$ENDIF}
       	qglBegin(GL_TRIANGLE_FAN);
	qglColor3f(light.color[0]*0.2, light.color[1]*0.2, light.color[2]*0.2);
        for i:=0 to 2 do
        v[i] := light.origin[i] - vpn[i]*rad;
	qglVertex3fv(@v);
	qglColor3f(0,0,0);
        for i:=16 downto 0 do
        begin
         a:=i/16*M_PI*2;
           for j:=0 to 2 do
             v[j]:=light.origin[j] + vright[j]*cos(a)*rad
	     	        		+ vup[j]*sin(a)*rad;
           qglVertex3fv(@v);
        end;
        qglEnd;

end;

procedure R_RenderDlights ;
var
i :integer ;
l :dlight_p;
begin
	 if (gl_flashblend.value <> 0) then
	 	exit;
	r_dlightframecount := r_framecount+1 ;	// because the count hasn't
                                                //  advanced yet for this frame
       	qglDepthMask (False);
       	qglDisable (GL_TEXTURE_2D);
       	qglShadeModel (GL_SMOOTH);
       	qglEnable (GL_BLEND);
       	qglBlendFunc (GL_ONE, GL_ONE);
	
	l := r_newrefdef.dlights ;
	for i:=0 to (r_newrefdef.num_dlights -1) do
	begin
	R_RenderDlight (l) ;
	
	qglColor3f (1,1,1);
	qglDisable (GL_BLEND);
	qglEnable (GL_TEXTURE_2D);
	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        qglDepthMask (True);
	inc (l);
	end;
end;

(*/*
=============================================================================

DYNAMIC LIGHTS

=============================================================================
*/*)


(*/*
=============
R_MarkLights
=============
*/*)
procedure R_MarkLights (light :dlight_p ;bit :integer ;node :mnode_p) ;
var
splitplane :cplane_p ;
dist :single ;
surf :msurface_p ;
i :integer ;
begin
	 if (node.contents <> -1) then 
	 	exit ;
	splitplane := node.plane ;
        dist := DotProduct (light.origin , splitplane.normal) - splitplane.dist ;
	
	if (dist > light.intensity - DLIGHT_CUTOFF) then
	begin
	R_MarkLights (light,bit,node.children[0]);
	exit;
	end;
	if (dist < -(light.intensity+DLIGHT_CUTOFF)) then
	begin
	R_MarkLights (light,bit,node.children[1]);
	exit;
	end;
// mark the polygons
   surf := r_worldmodel.surfaces + node.firstsurface ;
   for i:=0 to node.numsurfaces -1 do
   begin
   if surf.dlightframe <> r_dlightframecount then
   begin
   surf.dlightbits :=0 ;
   surf.dlightframe := r_dlightframecount ;
   end;
   surf.dlightbits := surf.dlightbits or bit;
   inc (surf);
   end;
   
   R_MarkLights (light, bit, node.children[0]);
   R_MarkLights (light, bit, node.children[1]);		
end;

(*/*
=============
R_PushDlights
=============
*/*)
procedure R_PushDlights ;
var 
i :integer ;
l : dlight_p;
begin
	 if (gl_flashblend.value > 0) then 
	 exit ;
	 
	r_dlightframecount := r_framecount + 1;	// because the count hasn't
                                                //  advanced yet for this frame
	l := r_newrefdef.dlights; 
	
	for i:=0 to r_newrefdef.num_dlights -1 do
	begin
	R_MarkLights (l ,1 shl i ,r_worldmodel.nodes);
	inc (l);
	end;

end;

(*/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/*)

function RecursiveLightPoint (node :mnode_p ; start:vec3_t; _end :vec3_t):integer ;
var
front , back ,frac :single ;
side :integer ;
plane :cplane_p ;
mid ,scale :vec3_t ;
surf :msurface_p ;
s,t,ds,dt,i :integer;
ii :integer;     // {FAB} added by me
tex : mtexinfo_p ;
lightmap :Array of byte ;
maps ,r :integer ;
begin
	 if (node.contents <> -1) then
         begin
	 result := -1 ;// didn't hit anything
	 exit ;
         end;
// calculate mid point

// FIXME: optimize for axial
   plane :=node.plane ;
   front := DotProduct (start , plane.normal) - plane.dist;
   back := DotProduct (_end ,plane.normal) - plane.dist;
   side := round(front) { < 0 };  //{Fab} Check this ...Original was    side = front < 0 ;

   if (round(back {< 0 } ) = side ) then   //{Fab} Check this ...Original was   if ( (back < 0) == side)
   begin
   result := RecursiveLightPoint (node.children[side],start ,_end);
   exit;
   end;

   frac :=front / (front-back);
   mid[0] := start[0] + (_end[0] - start[0])* frac ;
   mid[1] := start[1] + (_end[1] - start[1])*frac;
   mid[2] := start[2] + (_end[2] - start[2])*frac;
	
// go down front side
   r := RecursiveLightPoint (node.children[side], start, mid);
	if (r >= 0) then
        begin
	result := r;		// hit something
        exit;
        end;

	if  Round(back {< 0 } ) = side then   // {Fab} check this ..........
        begin
	result := -1; 	 // didn't hit anything
        exit;
        end;

        // check for impact on this node
        //
        VectorCopy ( mid , lightspot );
        lightplane := plane;
	
	 surf := r_worldmodel.surfaces + node.firstsurface;
	for i:=0 to node.numsurfaces -1 do 
	begin
	       //   if (surf.flags = SURF_DRAWTURB) or (surf.flags = SURF_DRAWSKY) then
               if (surf.flags and SURF_DRAWTURB or SURF_DRAWSKY) <> 0 then   // {Fab} check this
		continue ; // no lightmaps
		
		tex := surf.texinfo ;
		
	      	s := DotProduct (mid, tex.vecs[0]) + tex.vecs[0][3];
	      	t := DotProduct (mid, tex.vecs[1]) + tex.vecs[1][3];

		if (s < surf.texturemins [0] ) or (t < surf.texturemins[1] ) then 
		continue ;
			
    	        ds := s - surf.texturemins[0];
		dt := t - surf.texturemins[1]; 
		
		if ( ds > surf.extents[0]) or (dt > surf.extents[1] ) then 
		continue;
		
		if not assigned (surf.samples) then
                begin
		result := 0;
                exit;
                end;

		ds := ds shr 4 ;
		dt := dt shr 4 ;
		
		lightmap := surf.samples;
	       	VectorCopy (vec3_origin, pointcolor);
		if assigned(lightmap) then
		begin
	       	lightmap := lightmap + 3 * (dt * ((surf.extents[0] shr 4)+1)+ds);
		
		for maps := 0 to MAXLIGHTMAPS-1 do 
		begin
		if surf.styles [maps] <> 255 then break ;
		for ii:= 0 to 3 do
		begin 
	      	scale[ii] := gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps]].rgb[ii];

	       	pointcolor[0] :=pointcolor + lightmap[0] * scale[0] * (1.0/255);
	      	pointcolor[1] :=pointcolor + lightmap[1] * scale[1] * (1.0/255);
	      	pointcolor[2] :=pointcolor + lightmap[2] * scale[2] * (1.0/255);
	       	 lightmap := lightmap + 3* [((surf.extents[0] shr 4)+1) * ((surf.extents[1] shr 4)+1)];
		 end;
		 end;
		end;
		inc (surf);
	result := 1;
	end;
	result := RecursiveLightPoint (node.children [ not side],mid ,_end );	
end;

(*/*
===============
R_LightPoint
===============
*/*)
procedure R_LightPoint (p :vec3_t ;color :vec3_t);
var
_end : vec3_t;
r :single ;
lnum : integer;
dl :dlight_p ;
light :single ;
dist :vec3_t ;
add :single ;
begin
	 if not assigned(r_worldmodel.lightdata) then
	 begin
	 color[0] := 1;
	 color[1] := 1;
	 color[2] := 1;
	 exit ;
	 end;
	 
         _end[0] := p[0] ;
	 _end[1] := p[1];
	 _end[2] := p[2] - 2048;
	 
	 r := RecursiveLightPoint (r_worldmodel.nodes ,p ,_end);
	 
	        if (r = -1) then
	 	VectorCopy (vec3_origin ,color )
	        else ;
		 VectorCopy (pointcolor,color );
	
	//
	// add dynamic lights
	//

⌨️ 快捷键说明

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