- Implemented basic light source rendering
This commit is contained in:
parent
ee9a44219f
commit
7b46795bc1
|
@ -55,7 +55,7 @@
|
|||
<MinVersion Major="4" Minor="5" Release="1" Valid="True"/>
|
||||
</Item5>
|
||||
</RequiredPackages>
|
||||
<Units Count="42">
|
||||
<Units Count="43">
|
||||
<Unit0>
|
||||
<Filename Value="CentrED.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
|
@ -304,6 +304,11 @@
|
|||
<Filename Value="../version.inc"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit41>
|
||||
<Unit42>
|
||||
<Filename Value="ULightManager.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ULightManager"/>
|
||||
</Unit42>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@ -332,7 +337,6 @@
|
|||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="True"/>
|
||||
<UseExternalDbgSyms Value="True"/>
|
||||
</Debugging>
|
||||
<LinkSmart Value="True"/>
|
||||
<Options>
|
||||
|
|
|
@ -42,7 +42,8 @@ uses
|
|||
UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets,
|
||||
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
|
||||
Logging, UTileDataProvider, UMap, UWorldItem, UStatics, UTiledata, UAnimData,
|
||||
UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider;
|
||||
UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider,
|
||||
ULightManager;
|
||||
|
||||
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}
|
||||
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
(*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at
|
||||
* http://www.opensource.org/licenses/cddl1.php.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at
|
||||
* http://www.opensource.org/licenses/cddl1.php. If applicable,
|
||||
* add the following below this CDDL HEADER, with the fields enclosed
|
||||
* by brackets "[]" replaced with your own identifying * information:
|
||||
* Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*
|
||||
*
|
||||
* Portions Copyright 2009 Andreas Schneider
|
||||
*)
|
||||
unit ULightManager;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Imaging, ImagingTypes, ImagingClasses, ImagingCanvases,
|
||||
ImagingOpenGL, GL, fgl, ULandscape, UWorldItem;
|
||||
|
||||
type
|
||||
|
||||
TCalculateOffset = procedure(ARelativeX, ARelativeY: Integer; out DrawX,
|
||||
DrawY: Integer) of object;
|
||||
|
||||
{ TLightSource }
|
||||
|
||||
TLightSource = class
|
||||
constructor Create(AWorldItem: TWorldItem);
|
||||
protected
|
||||
FX: Integer;
|
||||
FY: Integer;
|
||||
FZ: smallint;
|
||||
public
|
||||
property X: Integer read FX;
|
||||
property Y: Integer read FY;
|
||||
property Z: smallint read FZ;
|
||||
end;
|
||||
|
||||
TLightSources = specialize TFPGObjectList<TLightSource>;
|
||||
|
||||
{ TLightManager }
|
||||
|
||||
TLightManager = class
|
||||
constructor Create(ACalculateOffset: TCalculateOffset);
|
||||
destructor Destroy; override;
|
||||
protected
|
||||
FLightSources: TLightSources;
|
||||
FOverlay: TSingleImage;
|
||||
FOverlayTexture: GLuint;
|
||||
FLightLevel: byte;
|
||||
FValid: Boolean;
|
||||
FCalculateOffset: TCalculateOffset;
|
||||
procedure UpdateOverlay(AScreenRect: TRect; FX, FY: Integer);
|
||||
public
|
||||
procedure UpdateLightMap(ALeft, AWidth, ATop, AHeight: Integer;
|
||||
AScreenBuffer: TScreenBuffer);
|
||||
procedure Draw(AScreenRect: TRect; FX, FY: Integer);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
UGameResources, UTiledata, UStatics, Logging;
|
||||
|
||||
{ TLightManager }
|
||||
|
||||
constructor TLightManager.Create(ACalculateOffset: TCalculateOffset);
|
||||
begin
|
||||
FCalculateOffset := ACalculateOffset;
|
||||
FLightSources := TLightSources.Create(True);
|
||||
FLightLevel := 15; //TODO : 0 ...
|
||||
end;
|
||||
|
||||
destructor TLightManager.Destroy;
|
||||
begin
|
||||
FreeAndNil(FLightSources);
|
||||
FreeAndNil(FOverlay);
|
||||
glDeleteTextures(1, @FOverlayTexture);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TLightManager.UpdateOverlay(AScreenRect: TRect; FX, FY: Integer);
|
||||
var
|
||||
canvas: TFastARGB32Canvas;
|
||||
color: TColor32Rec;
|
||||
i, drawX, drawY, drawZ: Integer;
|
||||
begin
|
||||
FOverlay.Free;
|
||||
glDeleteTextures(1, @FOverlayTexture);
|
||||
|
||||
color.A := $FF;
|
||||
color.R := ((32 - FLightLevel) * 255) div 32;
|
||||
color.G := color.R;
|
||||
color.B := color.R;
|
||||
|
||||
FOverlay := TSingleImage.CreateFromParams(AScreenRect.Right, AScreenRect.Bottom,
|
||||
ifA8R8G8B8);
|
||||
canvas := TFastARGB32Canvas.CreateForImage(FOverlay);
|
||||
try
|
||||
canvas.FillColor32 := color.Color;
|
||||
canvas.FillRect(AScreenRect);
|
||||
finally
|
||||
canvas.Free;
|
||||
end;
|
||||
|
||||
for i := 0 to FLightSources.Count - 1 do
|
||||
begin
|
||||
FCalculateOffset(FLightSources[i].X - FX, FLightSources[i].Y - FY,
|
||||
drawX, drawY);
|
||||
drawZ := FLightSources[i].Z * 4;
|
||||
color.A := $20;
|
||||
color.R := 220;
|
||||
color.G := 0;
|
||||
color.B := 0;
|
||||
canvas.FillColor32 := color.Color;
|
||||
canvas.FillRectBlend(Rect(drawX - 22, drawY - drawZ, drawX + 22,
|
||||
drawY + 44 - drawZ), bfOne, bfOne);
|
||||
end;
|
||||
|
||||
//TODO : PowerOfTwo!!!
|
||||
FOverlayTexture := CreateGLTextureFromImage(FOverlay.ImageDataPointer^);
|
||||
|
||||
FValid := True;
|
||||
end;
|
||||
|
||||
procedure TLightManager.UpdateLightMap(ALeft, AWidth, ATop, AHeight: Integer;
|
||||
AScreenBuffer: TScreenBuffer);
|
||||
var
|
||||
blockInfo: PBlockInfo;
|
||||
itemMap, lightMap: array of array of TWorldItem;
|
||||
x, y: Integer;
|
||||
begin
|
||||
//Logger.EnterMethod([lcClient, lcDebug], 'UpdateLightMap');
|
||||
FLightSources.Clear;
|
||||
{Logger.Send([lcClient, lcDebug], 'AWidth', AWidth);
|
||||
Logger.Send([lcClient, lcDebug], 'AHeight', AHeight);}
|
||||
SetLength(itemMap, AWidth, AHeight);
|
||||
SetLength(lightMap, AWidth, AHeight);
|
||||
for x := 0 to AWidth - 1 do
|
||||
for y := 0 to AHeight - 1 do
|
||||
begin
|
||||
itemMap[x, y] := nil;
|
||||
lightMap[x, y] := nil;
|
||||
end;
|
||||
|
||||
blockInfo := nil;
|
||||
while AScreenBuffer.Iterate(blockInfo) do
|
||||
begin
|
||||
if blockInfo^.State = ssNormal then
|
||||
begin
|
||||
x := blockInfo^.Item.X - ALeft;
|
||||
y := blockInfo^.Item.Y - ATop;
|
||||
itemMap[x, y] := blockInfo^.Item;
|
||||
if (blockInfo^.Item is TStaticItem) and (tdfLightSource in
|
||||
ResMan.Tiledata.StaticTiles[blockInfo^.Item.TileID].Flags) then
|
||||
lightMap[x, y] := blockInfo^.Item;
|
||||
end;
|
||||
end;
|
||||
|
||||
for x := 0 to AWidth - 2 do
|
||||
for y := 0 to AHeight - 2 do
|
||||
if lightMap[x, y] <> nil then
|
||||
begin
|
||||
if ((itemMap[x, y] = nil) or (itemMap[x, y].Z < lightMap[x, y].Z + 3)) or
|
||||
((itemMap[x + 1, y] = nil) or (itemMap[x + 1, y].Z < lightMap[x, y].Z + 3)) or
|
||||
((itemMap[x + 1, y + 1] = nil) or (itemMap[x + 1, y + 1].Z < lightMap[x, y].Z + 3)) or
|
||||
((itemMap[x, y + 1] = nil) or (itemMap[x, y + 1].Z < lightMap[x, y].Z + 3)) then
|
||||
begin
|
||||
FLightSources.Add(TLightSource.Create(lightMap[x, y]));
|
||||
end;
|
||||
end;
|
||||
FValid := False;
|
||||
//Logger.ExitMethod([lcClient, lcDebug], 'UpdateLightMap');
|
||||
end;
|
||||
|
||||
procedure TLightManager.Draw(AScreenRect: TRect; FX, FY: Integer);
|
||||
begin
|
||||
if not FValid then
|
||||
UpdateOverlay(AScreenRect, FX, FY);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, FOverlayTexture);
|
||||
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 0);
|
||||
glVertex2i(AScreenRect.Left, AScreenRect.Top);
|
||||
glTexCoord2i(0, 1);
|
||||
glVertex2i(AScreenRect.Left, AScreenRect.Bottom);
|
||||
glTexCoord2i(1, 1);
|
||||
glVertex2i(AScreenRect.Right, AScreenRect.Bottom);
|
||||
glTexCoord2i(1, 0);
|
||||
glVertex2i(AScreenRect.Right, AScreenRect.Top);
|
||||
glEnd;
|
||||
end;
|
||||
|
||||
{ TLightSource }
|
||||
|
||||
constructor TLightSource.Create(AWorldItem: TWorldItem);
|
||||
begin
|
||||
FX := AWorldItem.X;
|
||||
FY := AWorldItem.Y;
|
||||
FZ := AWorldItem.Z;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -224,6 +224,9 @@ procedure TOverlayUI.Draw(AContext: TOpenGLControl);
|
|||
begin
|
||||
if FVisible then
|
||||
begin
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
FArrows[0].DrawGL(10, 10, FActiveArrow = 0);
|
||||
FArrows[1].DrawGL(AContext.Width div 2 - FArrows[1].Width div 2, 10,
|
||||
FActiveArrow = 1);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
object frmMain: TfrmMain
|
||||
Left = 257
|
||||
Height = 579
|
||||
Top = 135
|
||||
Top = 141
|
||||
Width = 755
|
||||
ActiveControl = oglGameWindow
|
||||
Caption = 'UO CentrED'
|
||||
|
|
|
@ -35,7 +35,7 @@ uses
|
|||
StdCtrls, Spin, UEnums, VirtualTrees, Buttons, UMulBlock, UWorldItem, math,
|
||||
LCLIntf, UOverlayUI, UStatics, UEnhancedMemoryStream, ActnList,
|
||||
XMLPropStorage, fgl, ImagingClasses, dateutils, UPlatformTypes, UMap, UPacket,
|
||||
UGLFont, DOM, XMLRead, XMLWrite, strutils;
|
||||
UGLFont, DOM, XMLRead, XMLWrite, strutils, ULightManager;
|
||||
|
||||
type
|
||||
TAccessChangedListener = procedure(AAccessLevel: TAccessLevel) of object;
|
||||
|
@ -323,6 +323,7 @@ type
|
|||
FGLFont: TGLFont;
|
||||
FSelectionListeners: TSelectionListeners;
|
||||
FTileHint: TTileHintInfo;
|
||||
FLightManager: TLightManager;
|
||||
{ Methods }
|
||||
procedure BuildTileList;
|
||||
function ConfirmAction: Boolean;
|
||||
|
@ -892,6 +893,7 @@ begin
|
|||
edX.MaxValue := FLandscape.CellWidth;
|
||||
edY.MaxValue := FLandscape.CellHeight;
|
||||
FOverlayUI := TOverlayUI.Create;
|
||||
FLightManager := TLightManager.Create(@GetDrawOffset);
|
||||
|
||||
ProcessAccessLevel;
|
||||
|
||||
|
@ -1258,6 +1260,7 @@ begin
|
|||
FreeAndNil(FTextureManager);
|
||||
FreeAndNil(FScreenBuffer);
|
||||
FreeAndNil(FOverlayUI);
|
||||
FreeAndNil(FLightManager);
|
||||
FreeAndNil(FVLayerImage);
|
||||
FreeAndNil(FVLayerMaterial);
|
||||
FreeAndNil(FVirtualTiles);
|
||||
|
@ -2387,7 +2390,7 @@ begin
|
|||
blockInfo^.Text.Render(blockInfo^.ScreenRect);
|
||||
end;
|
||||
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
FLightManager.Draw(oglGameWindow.ClientRect, FX, FY);
|
||||
FOverlayUI.Draw(oglGameWindow);
|
||||
end;
|
||||
|
||||
|
@ -2729,6 +2732,10 @@ begin
|
|||
end;
|
||||
end;
|
||||
Include(FScreenBufferState, sbsFiltered);
|
||||
|
||||
//TODO : Check lightlevel first
|
||||
FLightManager.UpdateLightMap(FX + FLowOffsetX, FRangeX + 1, FY + FLowOffsetY,
|
||||
FRangeY + 1, FScreenBuffer);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.UpdateSelection;
|
||||
|
|
Loading…
Reference in New Issue