📄 gl_light.pas
字号:
// 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 + -