- Added TAnimMaterial

- Implemented animated tiles
- Fixed TAnimData.FrameData to use ShortInt instead of Byte
This commit is contained in:
Andreas Schneider 2009-12-09 16:26:12 +01:00
parent 2a3e17fa57
commit be935a6bcb
3 changed files with 104 additions and 6 deletions

View File

@ -33,7 +33,7 @@ uses
SysUtils, Classes, math, LCLIntf, GL, GLu, ImagingOpenGL, Imaging, SysUtils, Classes, math, LCLIntf, GL, GLu, ImagingOpenGL, Imaging,
ImagingClasses, ImagingTypes, ImagingUtility, ImagingClasses, ImagingTypes, ImagingUtility,
UGenericIndex, UMap, UStatics, UArt, UTexture, UTiledata, UHue, UWorldItem, UGenericIndex, UMap, UStatics, UArt, UTexture, UTiledata, UHue, UWorldItem,
UMulBlock, UMulBlock, UAnimData,
UVector, UEnhancedMemoryStream, UGLFont, UVector, UEnhancedMemoryStream, UGLFont,
UCacheManager; UCacheManager;
@ -72,6 +72,17 @@ type
constructor Create(AGraphic: TBaseImage); constructor Create(AGraphic: TBaseImage);
end; end;
{ TAnimMaterial }
TAnimMaterial = class(TMaterial)
constructor Create(ABaseID: Word; AAnimData: TAnimData; AHue: THue = nil;
APartialHue: Boolean = False);
protected
FNextChange: DWord;
FAnimData: TAnimData;
function GetTexture: GLuint; override;
end;
TMaterialCache = specialize TCacheManager<TMaterial>; TMaterialCache = specialize TCacheManager<TMaterial>;
{ TLandTextureManager } { TLandTextureManager }
@ -83,6 +94,7 @@ type
FArtCache: TMaterialCache; FArtCache: TMaterialCache;
FFlatLandArtCache: TMaterialCache; FFlatLandArtCache: TMaterialCache;
FTexCache: TMaterialCache; FTexCache: TMaterialCache;
FAnimations: TMaterialCache;
public public
function GetArtMaterial(ATileID: Word): TMaterial; overload; function GetArtMaterial(ATileID: Word): TMaterial; overload;
function GetArtMaterial(ATileID: Word; AHue: THue; function GetArtMaterial(ATileID: Word; AHue: THue;
@ -289,6 +301,7 @@ begin
FArtCache := TMaterialCache.Create(1024); FArtCache := TMaterialCache.Create(1024);
FFlatLandArtCache := TMaterialCache.Create(128); FFlatLandArtCache := TMaterialCache.Create(128);
FTexCache := TMaterialCache.Create(128); FTexCache := TMaterialCache.Create(128);
FAnimations := TMaterialCache.Create(128);
end; end;
destructor TLandTextureManager.Destroy; destructor TLandTextureManager.Destroy;
@ -296,14 +309,28 @@ begin
FreeAndNil(FArtCache); FreeAndNil(FArtCache);
FreeAndNil(FFlatLandArtCache); FreeAndNil(FFlatLandArtCache);
FreeAndNil(FTexCache); FreeAndNil(FTexCache);
FreeAndNil(FAnimations);
inherited Destroy; inherited Destroy;
end; end;
function TLandTextureManager.GetArtMaterial(ATileID: Word): TMaterial; function TLandTextureManager.GetArtMaterial(ATileID: Word): TMaterial;
var var
artEntry: TArt; artEntry: TArt;
animData: TAnimData;
begin begin
if not FArtCache.QueryID(ATileID, Result) then Result := nil;
if ATileID >= $4000 then
begin
animData := ResMan.Animdata.AnimData[ATileID - $4000];
if (animData.FrameCount > 0) and not FAnimations.QueryID(ATileID, Result) then
begin
Result := TAnimMaterial.Create(ATileID, animData);
FAnimations.StoreID(ATileID, Result);
end;
end;
if (Result = nil) and not FArtCache.QueryID(ATileID, Result) then
begin begin
artEntry := TArt(ResMan.Art.Block[ATileID]); artEntry := TArt(ResMan.Art.Block[ATileID]);
@ -318,6 +345,7 @@ function TLandTextureManager.GetArtMaterial(ATileID: Word; AHue: THue;
APartialHue: Boolean): TMaterial; APartialHue: Boolean): TMaterial;
var var
artEntry: TArt; artEntry: TArt;
animData: TAnimData;
id: Integer; id: Integer;
begin begin
if AHue = nil then if AHue = nil then
@ -325,8 +353,20 @@ begin
Result := GetArtMaterial(ATileID); Result := GetArtMaterial(ATileID);
end else end else
begin begin
Result := nil;
id := ATileID or ((AHue.ID and $3FFF) shl 16) or (Byte(APartialHue) shl 30); id := ATileID or ((AHue.ID and $3FFF) shl 16) or (Byte(APartialHue) shl 30);
if not FArtCache.QueryID(id, Result) then
if ATileID >= $4000 then
begin
animData := ResMan.Animdata.AnimData[ATileID - $4000];
if (animData.FrameCount > 0) and not FAnimations.QueryID(id, Result) then
begin
Result := TAnimMaterial.Create(ATileID, animData, AHue, APartialHue);
FAnimations.StoreID(id, Result);
end;
end;
if (Result = nil) and not FArtCache.QueryID(id, Result) then
begin begin
artEntry := ResMan.Art.GetArt(ATileID, 0, AHue, APartialHue); artEntry := ResMan.Art.GetArt(ATileID, 0, AHue, APartialHue);
@ -1525,5 +1565,63 @@ begin
UpdateTexture; UpdateTexture;
end; end;
{ TAnimMaterial }
constructor TAnimMaterial.Create(ABaseID: Word; AAnimData: TAnimData;
AHue: THue = nil; APartialHue: Boolean = False);
var
i: Integer;
art: TArt;
begin
//Logger.EnterMethod([lcLandscape, lcClient, lcDebug], 'TAnimMaterial.Create');
FAnimData := AAnimData;
FGraphic := TMultiImage.Create;
FRealWidth := 0;
FRealHeight := 0;
for i := 0 to AAnimData.FrameCount - 1 do
begin
{Logger.Send([lcLandscape, lcClient, lcDebug], 'Processing frame', i);
Logger.Send([lcLandscape, lcClient, lcDebug], 'FrameData', AAnimData.FrameData[i]);}
art := ResMan.Art.GetArt(ABaseID + AAnimData.FrameData[i], 0, AHue,
APartialHue);
if (art.Graphic.Width > FRealWidth) or
(art.Graphic.Height > FRealHeight) then
begin
FRealWidth := art.Graphic.Width;
FRealHeight := art.Graphic.Height;
end;
FGraphic.AddImage(art.Graphic);
art.Free;
end;
FGraphic.DeleteImage(0); //Delete the image that was created during TMultiImage.Create
FGraphic.ActiveImage := 0;
FNextChange := GetTickCount + AAnimData.FrameStart * 100;
UpdateTexture;
//Logger.ExitMethod([lcLandscape, lcClient, lcDebug], 'TAnimMaterial.Create');
end;
function TAnimMaterial.GetTexture: GLuint;
begin
if FNextChange <= GetTickCount then
begin
FGraphic.ActiveImage := (FGraphic.ActiveImage + 1) mod FAnimData.FrameCount;
if FGraphic.ActiveImage = 0 then
FNextChange := GetTickCount + FAnimData.FrameStart * 100
else
FNextChange:= GetTickCount + FAnimData.FrameInterval * 100;
UpdateTexture;
end;
Result := FTexture;
end;
end. end.

View File

@ -983,9 +983,9 @@ end;
procedure TfrmMain.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean); procedure TfrmMain.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
begin begin
if (FScreenBufferState <> CScreenBufferValid) or if (FScreenBufferState <> CScreenBufferValid) or
(FRepaintNeeded and (MilliSecondsBetween(Now, FLastDraw) > 50)) then ({FRepaintNeeded and }(MilliSecondsBetween(Now, FLastDraw) > 50)) then
begin begin
Logger.Send([lcClient, lcDebug], 'Repainting Game Window'); //Logger.Send([lcClient, lcDebug], 'Repainting Game Window');
oglGameWindow.Repaint; oglGameWindow.Repaint;
FLastDraw := Now; FLastDraw := Now;
FRepaintNeeded := False; FRepaintNeeded := False;

View File

@ -49,7 +49,7 @@ type
FFrameInterval: Byte; FFrameInterval: Byte;
FFrameStart: Byte; FFrameStart: Byte;
public public
FrameData: array[0..63] of Byte; FrameData: array[0..63] of ShortInt;
property Unknown: Byte read FUnknown write FUnknown; property Unknown: Byte read FUnknown write FUnknown;
property FrameCount: Byte read FFrameCount write FFrameCount; property FrameCount: Byte read FFrameCount write FFrameCount;
property FrameInterval: Byte read FFrameInterval write FFrameInterval; property FrameInterval: Byte read FFrameInterval write FFrameInterval;