- Added light loading

- Use lights for the light sources
This commit is contained in:
Andreas Schneider 2009-12-21 00:13:26 +01:00
parent 7b46795bc1
commit 5049955303
8 changed files with 564 additions and 257 deletions

View File

@ -55,7 +55,7 @@
<MinVersion Major="4" Minor="5" Release="1" Valid="True"/> <MinVersion Major="4" Minor="5" Release="1" Valid="True"/>
</Item5> </Item5>
</RequiredPackages> </RequiredPackages>
<Units Count="43"> <Units Count="45">
<Unit0> <Unit0>
<Filename Value="CentrED.lpr"/> <Filename Value="CentrED.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -309,6 +309,16 @@
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ULightManager"/> <UnitName Value="ULightManager"/>
</Unit42> </Unit42>
<Unit43>
<Filename Value="../UOLib/ULight.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ULight"/>
</Unit43>
<Unit44>
<Filename Value="../MulProvider/ULightProvider.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ULightProvider"/>
</Unit44>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -43,7 +43,7 @@ uses
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow, UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
Logging, UTileDataProvider, UMap, UWorldItem, UStatics, UTiledata, UAnimData, Logging, UTileDataProvider, UMap, UWorldItem, UStatics, UTiledata, UAnimData,
UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider, UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider,
ULightManager; ULightManager, ULight, ULightProvider;
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF} {$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}

View File

@ -31,23 +31,24 @@ interface
uses uses
Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider, Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider,
ULandscape, UHueProvider, UAnimDataProvider; ULandscape, UHueProvider, UAnimDataProvider, ULightProvider;
type type
{ TGameResourceManager } { TGameResourceManager }
TGameResourceManager = class TGameResourceManager = class
constructor Create(ADataDir: string); constructor Create(ADataDir: String);
destructor Destroy; override; destructor Destroy; override;
protected protected
{ Members } { Members }
FDataDir: string; FDataDir: String;
FArtProvider: TArtProvider; FArtProvider: TArtProvider;
FTiledataProvider: TTiledataProvider; FTiledataProvider: TTiledataProvider;
FAnimdataProvider: TAnimdataProvider; FAnimdataProvider: TAnimdataProvider;
FTexmapProvider: TTexmapProvider; FTexmapProvider: TTexmapProvider;
FHueProvider: THueProvider; FHueProvider: THueProvider;
FLightProvider: TLightProvider;
FLandscape: TLandscape; FLandscape: TLandscape;
public public
{ Fields } { Fields }
@ -57,9 +58,10 @@ type
property Tiledata: TTiledataProvider read FTiledataProvider; property Tiledata: TTiledataProvider read FTiledataProvider;
property Animdata: TAnimDataProvider read FAnimdataProvider; property Animdata: TAnimDataProvider read FAnimdataProvider;
property Texmaps: TTexmapProvider read FTexmapProvider; property Texmaps: TTexmapProvider read FTexmapProvider;
property Lights: TLightProvider read FLightProvider;
{ Methods } { Methods }
function GetFile(AFileName: string): string; function GetFile(AFileName: String): String;
procedure InitLandscape(AWidth, AHeight: Word); procedure InitLandscape(AWidth, AHeight: Word);
end; end;
@ -67,11 +69,11 @@ var
GameResourceManager: TGameResourceManager; GameResourceManager: TGameResourceManager;
ResMan: TGameResourceManager absolute GameResourceManager; ResMan: TGameResourceManager absolute GameResourceManager;
procedure InitGameResourceManager(ADataDir: string); procedure InitGameResourceManager(ADataDir: String);
implementation implementation
procedure InitGameResourceManager(ADataDir: string); procedure InitGameResourceManager(ADataDir: String);
begin begin
FreeAndNil(GameResourceManager); FreeAndNil(GameResourceManager);
GameResourceManager := TGameResourceManager.Create(ADataDir); GameResourceManager := TGameResourceManager.Create(ADataDir);
@ -79,7 +81,7 @@ end;
{ TGameResourceManager } { TGameResourceManager }
constructor TGameResourceManager.Create(ADataDir: string); constructor TGameResourceManager.Create(ADataDir: String);
begin begin
inherited Create; inherited Create;
FDataDir := IncludeTrailingPathDelimiter(ADataDir); FDataDir := IncludeTrailingPathDelimiter(ADataDir);
@ -87,8 +89,11 @@ begin
FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True); FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True);
FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True); FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True);
FAnimdataProvider := TAnimDataProvider.Create(GetFile('animdata.mul'), True); FAnimdataProvider := TAnimDataProvider.Create(GetFile('animdata.mul'), True);
FTexmapProvider := TTexmapProvider.Create(GetFile('texmaps.mul'), GetFile('texidx.mul'), True); FTexmapProvider := TTexmapProvider.Create(GetFile('texmaps.mul'),
GetFile('texidx.mul'), True);
FHueProvider := THueProvider.Create(GetFile('hues.mul'), True); FHueProvider := THueProvider.Create(GetFile('hues.mul'), True);
FLightProvider := TLightProvider.Create(GetFile('light.mul'),
GetFile('lightidx.mul'), True);
end; end;
destructor TGameResourceManager.Destroy; destructor TGameResourceManager.Destroy;
@ -98,11 +103,12 @@ begin
FreeAndNil(FAnimdataProvider); FreeAndNil(FAnimdataProvider);
FreeAndNil(FTexmapProvider); FreeAndNil(FTexmapProvider);
FreeAndNil(FHueProvider); FreeAndNil(FHueProvider);
FreeAndNil(FLightProvider);
FreeAndNil(FLandscape); FreeAndNil(FLandscape);
inherited Destroy; inherited Destroy;
end; end;
function TGameResourceManager.GetFile(AFileName: string): string; function TGameResourceManager.GetFile(AFileName: String): String;
begin begin
Result := FDataDir + AFileName; Result := FDataDir + AFileName;
end; end;
@ -117,4 +123,3 @@ finalization
FreeAndNil(GameResourceManager); FreeAndNil(GameResourceManager);
end. end.

View File

@ -31,25 +31,51 @@ interface
uses uses
Classes, SysUtils, Imaging, ImagingTypes, ImagingClasses, ImagingCanvases, Classes, SysUtils, Imaging, ImagingTypes, ImagingClasses, ImagingCanvases,
ImagingOpenGL, GL, fgl, ULandscape, UWorldItem; ImagingOpenGL, GL, fgl, ULandscape, UWorldItem, UCacheManager;
type type
TCalculateOffset = procedure(ARelativeX, ARelativeY: Integer; out DrawX, TCalculateOffset = procedure(AX, AY: Integer; out DrawX, DrawY: Integer) of object;
DrawY: Integer) of object;
{ TLightMaterial }
TLightMaterial = class(ICacheable)
constructor Create(AGraphic: TBaseImage);
destructor Destroy; override;
protected
FRefCount: Integer;
FGraphic: TSingleImage;
FCanvas: TFastARGB32Canvas;
public
property Graphic: TSingleImage read FGraphic;
property Canvas: TFastARGB32Canvas read FCanvas;
procedure AddRef;
procedure DelRef;
{ICacheable}
function CanBeRemoved: Boolean;
procedure RemoveFromCache;
end;
TLightCache = specialize TCacheManager<TLightMaterial>;
TLightManager = class;
{ TLightSource } { TLightSource }
TLightSource = class TLightSource = class
constructor Create(AWorldItem: TWorldItem); constructor Create(AManager: TLightManager; AWorldItem: TWorldItem);
destructor Destroy; override;
protected protected
FX: Integer; FX: Integer;
FY: Integer; FY: Integer;
FZ: smallint; FZ: smallint;
FMaterial: TLightMaterial;
public public
property X: Integer read FX; property X: Integer read FX;
property Y: Integer read FY; property Y: Integer read FY;
property Z: smallint read FZ; property Z: smallint read FZ;
property Material: TLightMaterial read FMaterial;
end; end;
TLightSources = specialize TFPGObjectList<TLightSource>; TLightSources = specialize TFPGObjectList<TLightSource>;
@ -57,7 +83,8 @@ type
{ TLightManager } { TLightManager }
TLightManager = class TLightManager = class
constructor Create(ACalculateOffset: TCalculateOffset); constructor Create(ACalculateOffset: TCalculateOffset;
ALandTextureManager: TLandTextureManager);
destructor Destroy; override; destructor Destroy; override;
protected protected
FLightSources: TLightSources; FLightSources: TLightSources;
@ -66,40 +93,65 @@ type
FLightLevel: byte; FLightLevel: byte;
FValid: Boolean; FValid: Boolean;
FCalculateOffset: TCalculateOffset; FCalculateOffset: TCalculateOffset;
procedure UpdateOverlay(AScreenRect: TRect; FX, FY: Integer); FLightCache: TLightCache;
FLandTextureManager: TLandTextureManager;
function GetLight(AID: Integer): TLightMaterial;
procedure UpdateOverlay(AScreenRect: TRect);
public public
procedure UpdateLightMap(ALeft, AWidth, ATop, AHeight: Integer; procedure UpdateLightMap(ALeft, AWidth, ATop, AHeight: Integer;
AScreenBuffer: TScreenBuffer); AScreenBuffer: TScreenBuffer);
procedure Draw(AScreenRect: TRect; FX, FY: Integer); procedure Draw(AScreenRect: TRect);
end; end;
implementation implementation
uses uses
UGameResources, UTiledata, UStatics, Logging; UGameResources, UTiledata, UStatics, ULight, Logging;
{ TLightManager } { TLightManager }
constructor TLightManager.Create(ACalculateOffset: TCalculateOffset); constructor TLightManager.Create(ACalculateOffset: TCalculateOffset;
ALandTextureManager: TLandTextureManager);
begin begin
FCalculateOffset := ACalculateOffset; FCalculateOffset := ACalculateOffset;
FLightSources := TLightSources.Create(True); FLightSources := TLightSources.Create(True);
FLightLevel := 15; //TODO : 0 ... FLightLevel := 15; //TODO : 0 ...
FLightCache := TLightCache.Create(32);
FLandTextureManager := ALandTextureManager;
end; end;
destructor TLightManager.Destroy; destructor TLightManager.Destroy;
begin begin
FreeAndNil(FLightSources); FreeAndNil(FLightSources);
FreeAndNil(FOverlay); FreeAndNil(FOverlay);
FreeAndNil(FLightCache);
glDeleteTextures(1, @FOverlayTexture); glDeleteTextures(1, @FOverlayTexture);
inherited Destroy; inherited Destroy;
end; end;
procedure TLightManager.UpdateOverlay(AScreenRect: TRect; FX, FY: Integer); function TLightManager.GetLight(AID: Integer): TLightMaterial;
var var
canvas: TFastARGB32Canvas; light: TLight;
begin
Result := nil;
if not FLightCache.QueryID(AID, Result) then
begin
if ResMan.Lights.Exists(AID) then
begin
light := ResMan.Lights.GetLight(AID);
Result := TLightMaterial.Create(light.Graphic);
FLightCache.StoreID(AID, Result);
light.Free;
end;
end;
end;
procedure TLightManager.UpdateOverlay(AScreenRect: TRect);
var
canvas, lightCanvas: TFastARGB32Canvas;
color: TColor32Rec; color: TColor32Rec;
i, drawX, drawY, drawZ: Integer; i: Integer;
lightMaterial: TLightMaterial;
begin begin
FOverlay.Free; FOverlay.Free;
glDeleteTextures(1, @FOverlayTexture); glDeleteTextures(1, @FOverlayTexture);
@ -121,16 +173,13 @@ begin
for i := 0 to FLightSources.Count - 1 do for i := 0 to FLightSources.Count - 1 do
begin begin
FCalculateOffset(FLightSources[i].X - FX, FLightSources[i].Y - FY, lightMaterial := FLightSources[i].Material;
drawX, drawY); if lightMaterial <> nil then
drawZ := FLightSources[i].Z * 4; begin
color.A := $20; lightMaterial.Canvas.DrawAdd(lightMaterial.Canvas.ClipRect, canvas,
color.R := 220; FLightSources[i].FX - lightMaterial.Graphic.Width div 2,
color.G := 0; FLightSources[i].FY - lightMaterial.Graphic.Height div 2);
color.B := 0; end;
canvas.FillColor32 := color.Color;
canvas.FillRectBlend(Rect(drawX - 22, drawY - drawZ, drawX + 22,
drawY + 44 - drawZ), bfOne, bfOne);
end; end;
//TODO : PowerOfTwo!!! //TODO : PowerOfTwo!!!
@ -182,17 +231,17 @@ begin
((itemMap[x + 1, y + 1] = nil) or (itemMap[x + 1, y + 1].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 ((itemMap[x, y + 1] = nil) or (itemMap[x, y + 1].Z < lightMap[x, y].Z + 3)) then
begin begin
FLightSources.Add(TLightSource.Create(lightMap[x, y])); FLightSources.Add(TLightSource.Create(Self, lightMap[x, y]));
end; end;
end; end;
FValid := False; FValid := False;
//Logger.ExitMethod([lcClient, lcDebug], 'UpdateLightMap'); //Logger.ExitMethod([lcClient, lcDebug], 'UpdateLightMap');
end; end;
procedure TLightManager.Draw(AScreenRect: TRect; FX, FY: Integer); procedure TLightManager.Draw(AScreenRect: TRect);
begin begin
if not FValid then if not FValid then
UpdateOverlay(AScreenRect, FX, FY); UpdateOverlay(AScreenRect);
glBindTexture(GL_TEXTURE_2D, FOverlayTexture); glBindTexture(GL_TEXTURE_2D, FOverlayTexture);
glBlendFunc(GL_ZERO, GL_SRC_COLOR); glBlendFunc(GL_ZERO, GL_SRC_COLOR);
@ -210,11 +259,67 @@ end;
{ TLightSource } { TLightSource }
constructor TLightSource.Create(AWorldItem: TWorldItem); constructor TLightSource.Create(AManager: TLightManager; AWorldItem: TWorldItem);
var
lightID: Byte;
itemMaterial: TMaterial;
begin begin
FX := AWorldItem.X; lightID := ResMan.Tiledata.StaticTiles[AWorldItem.TileID].Quality;
FY := AWorldItem.Y; FMaterial := AManager.GetLight(lightID);
FZ := AWorldItem.Z; if FMaterial <> nil then
begin
itemMaterial := AManager.FLandTextureManager.GetStaticMaterial(
TStaticItem(AWorldItem));
AManager.FCalculateOffset(AWorldItem.X, AWorldItem.Y, FX, FY);
FZ := AWorldItem.Z * 4;
FY := FY + 44 - FZ - itemMaterial.RealHeight div 2;
FMaterial.AddRef;
end;
end;
destructor TLightSource.Destroy;
begin
if FMaterial <> nil then
FMaterial.DelRef;
inherited Destroy;
end;
{ TLightMaterial }
constructor TLightMaterial.Create(AGraphic: TBaseImage);
begin
FRefCount := 1;
FGraphic := TSingleImage.CreateFromImage(AGraphic);
FCanvas := TFastARGB32Canvas.CreateForImage(FGraphic);
end;
destructor TLightMaterial.Destroy;
begin
FreeAndNil(FCanvas);
FreeAndNil(FGraphic);
inherited Destroy;
end;
procedure TLightMaterial.AddRef;
begin
Inc(FRefCount);
end;
procedure TLightMaterial.DelRef;
begin
Dec(FRefCount);
if FRefCount < 1 then
Free;
end;
function TLightMaterial.CanBeRemoved: Boolean;
begin
Result := (FRefCount <= 1);
end;
procedure TLightMaterial.RemoveFromCache;
begin
DelRef;
end; end;
end. end.

View File

@ -329,8 +329,7 @@ type
function ConfirmAction: Boolean; function ConfirmAction: Boolean;
function FindRandomPreset(AName: String): TDOMElement; function FindRandomPreset(AName: String): TDOMElement;
procedure ForceUpdateCurrentTile; procedure ForceUpdateCurrentTile;
procedure GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX, procedure GetDrawOffset(AX, AY: Integer; out DrawX, DrawY: Integer); inline;
DrawY: Integer); inline;
function GetInternalTileID(ATile: TWorldItem): Word; function GetInternalTileID(ATile: TWorldItem): Word;
function GetSelectedRect: TRect; function GetSelectedRect: TRect;
procedure InitRender; procedure InitRender;
@ -893,7 +892,7 @@ begin
edX.MaxValue := FLandscape.CellWidth; edX.MaxValue := FLandscape.CellWidth;
edY.MaxValue := FLandscape.CellHeight; edY.MaxValue := FLandscape.CellHeight;
FOverlayUI := TOverlayUI.Create; FOverlayUI := TOverlayUI.Create;
FLightManager := TLightManager.Create(@GetDrawOffset); FLightManager := TLightManager.Create(@GetDrawOffset, FTextureManager);
ProcessAccessLevel; ProcessAccessLevel;
@ -2161,7 +2160,7 @@ begin
item := ABlockInfo^.Item; item := ABlockInfo^.Item;
GetDrawOffset(item.X - FX, item.Y - FY, drawX, drawY); GetDrawOffset(item.X , item.Y, drawX, drawY);
if acFlat.Checked then if acFlat.Checked then
begin begin
@ -2390,7 +2389,7 @@ begin
blockInfo^.Text.Render(blockInfo^.ScreenRect); blockInfo^.Text.Render(blockInfo^.ScreenRect);
end; end;
FLightManager.Draw(oglGameWindow.ClientRect, FX, FY); FLightManager.Draw(oglGameWindow.ClientRect);
FOverlayUI.Draw(oglGameWindow); FOverlayUI.Draw(oglGameWindow);
end; end;
@ -3079,11 +3078,12 @@ begin
UpdateCurrentTile; UpdateCurrentTile;
end; end;
procedure TfrmMain.GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX, procedure TfrmMain.GetDrawOffset(AX, AY: Integer; out DrawX, DrawY: Integer); inline;
DrawY: Integer); inline;
begin begin
DrawX := (oglGameWindow.Width div 2) + (ARelativeX - ARelativeY) * 22; Dec(AX, FX);
DrawY := (oglGamewindow.Height div 2) + (ARelativeX + ARelativeY) * 22; Dec(AY, FY);
DrawX := (oglGameWindow.Width div 2) + (AX - AY) * 22;
DrawY := (oglGamewindow.Height div 2) + (AX + AY) * 22;
end; end;
initialization initialization

View File

@ -36,7 +36,8 @@ type
TArtProvider = class(TIndexedMulProvider) TArtProvider = class(TIndexedMulProvider)
protected protected
function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override; function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override;
function GetArtData(AID: Integer; AIndex: TGenericIndex; AColor: Word; AHue: THue; APartialHue: Boolean): TArt; function GetArtData(AID: Integer; AIndex: TGenericIndex; AColor: Word;
AHue: THue; APartialHue: Boolean): TArt;
public public
function GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt; function GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
function GetFlatLand(AID: Integer): TArt; function GetFlatLand(AID: Integer): TArt;
@ -60,7 +61,8 @@ begin
Result := TArt.Create(FData, AIndex, atLand, AColor, AHue, APartialHue) Result := TArt.Create(FData, AIndex, atLand, AColor, AHue, APartialHue)
else else
Result := TArt.Create(FData, AIndex, atStatic, AColor, AHue, APartialHue); Result := TArt.Create(FData, AIndex, atStatic, AColor, AHue, APartialHue);
end else end
else
begin begin
if AID < $4000 then if AID < $4000 then
Result := TArt.Create(nil, nil, atLand, AColor, AHue, APartialHue) Result := TArt.Create(nil, nil, atLand, AColor, AHue, APartialHue)
@ -70,7 +72,8 @@ begin
Result.ID := AID; Result.ID := AID;
end; end;
function TArtProvider.GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt; function TArtProvider.GetArt(AID: Integer; AColor: Word; AHue: THue;
APartialHue: Boolean): TArt;
var var
genericIndex: TGenericIndex; genericIndex: TGenericIndex;
begin begin
@ -95,3 +98,4 @@ begin
end; end;
end. end.

View File

@ -0,0 +1,62 @@
(*
* 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 ULightProvider;
{$mode objfpc}{$H+}
interface
uses
UMulProvider, UMulBlock, UGenericIndex, ULight;
type
{ TLightProvider }
TLightProvider = class(TIndexedMulProvider)
protected
function GetData(AID: Integer; AIndex: TGenericIndex): TLight; override;
public
function GetLight(AID: Integer): TLight;
end;
implementation
{ TLightProvider }
function TLightProvider.GetData(AID: Integer; AIndex: TGenericIndex): TLight;
begin
Result := TLight.Create(FData, AIndex);
Result.ID := AID;
end;
function TLightProvider.GetLight(AID: Integer): TLight;
begin
Result := TLight(GetBlock(AID));
end;
end.

121
UOLib/ULight.pas Normal file
View File

@ -0,0 +1,121 @@
(*
* 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 ULight;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Imaging, ImagingClasses, ImagingTypes, UMulBlock,
UGenericIndex;
type
{ TLight }
TLight = class(TMulBlock)
constructor Create(AData: TStream; AIndex: TGenericIndex);
destructor Destroy; override;
function Clone: TLight; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
protected
FGraphic: TSingleImage;
public
property Graphic: TSingleImage read FGraphic;
end;
implementation
{ TLight }
constructor TLight.Create(AData: TStream; AIndex: TGenericIndex);
var
buffer: TMemoryStream;
Width, Height: Word;
color: Byte;
color32: TColor32Rec;
x, y: Integer;
begin
if (AIndex <> nil) and (AIndex.Lookup > -1) and (AIndex.Size > 0) then
begin
Width := word(AIndex.Various shr 16);
Height := AIndex.Various and $FFFF;
FGraphic := TSingleImage.CreateFromParams(Width, Height, ifA8R8G8B8);
if AData <> nil then
begin
AData.Position := AIndex.Lookup;
buffer := TMemoryStream.Create;
buffer.CopyFrom(AData, AIndex.Size);
buffer.Position := 0;
for y := 0 to Height - 1 do
for x := 0 to Width - 1 do
begin
buffer.Read(color, SizeOf(byte));
color32.R := color * 8;
color32.G := color32.R;
color32.B := color32.R;
if color > 0 then
color32.A := 255
else
color32.A := 0;
PColor32(FGraphic.PixelPointers[x, y])^ := color32.Color;
end;
buffer.Free;
end;
end;
if FGraphic = nil then
FGraphic := TSingleImage.CreateFromParams(0, 0, ifA8R8G8B8);
end;
destructor TLight.Destroy;
begin
FreeAndNil(FGraphic);
inherited Destroy;
end;
function TLight.Clone: TLight;
begin
Result := TLight.Create(nil, nil);
Result.Graphic.Assign(FGraphic);
end;
function TLight.GetSize: Integer;
begin
Result := 0;
raise Exception.Create('Not implemented: TLight.GetSize');
end;
procedure TLight.Write(AData: TStream);
begin
raise Exception.Create('Not implemented: TLight.Write');
end;
end.