- Reimplemented the Virtual Layer

This commit is contained in:
Andreas Schneider 2009-09-29 02:25:19 +02:00
parent 99c21fa951
commit 0cee996fbc
4 changed files with 101 additions and 79 deletions

View File

@ -3,6 +3,7 @@ inherited frmVirtualLayer: TfrmVirtualLayer
Height = 82 Height = 82
Top = 171 Top = 171
Width = 210 Width = 210
ActiveControl = cbShowLayer
Caption = 'Virtual Layer' Caption = 'Virtual Layer'
ClientHeight = 82 ClientHeight = 82
ClientWidth = 210 ClientWidth = 210
@ -13,8 +14,8 @@ inherited frmVirtualLayer: TfrmVirtualLayer
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 8 Left = 8
Height = 33 Height = 36
Top = 41 Top = 37
Width = 194 Width = 194
Frequency = 10 Frequency = 10
Max = 127 Max = 127
@ -31,11 +32,12 @@ inherited frmVirtualLayer: TfrmVirtualLayer
AnchorSideTop.Control = seZ AnchorSideTop.Control = seZ
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 8 Left = 8
Height = 19 Height = 22
Top = 11 Top = 7
Width = 106 Width = 126
BorderSpacing.Left = 8 BorderSpacing.Left = 8
Caption = 'Show Layer at Z:' Caption = 'Show Layer at Z:'
OnChange = cbShowLayerChange
TabOrder = 1 TabOrder = 1
end end
object seZ: TSpinEdit[2] object seZ: TSpinEdit[2]
@ -43,7 +45,7 @@ inherited frmVirtualLayer: TfrmVirtualLayer
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 152 Left = 152
Height = 25 Height = 21
Top = 8 Top = 8
Width = 50 Width = 50
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
@ -51,6 +53,7 @@ inherited frmVirtualLayer: TfrmVirtualLayer
BorderSpacing.Right = 8 BorderSpacing.Right = 8
MaxValue = 127 MaxValue = 127
MinValue = -128 MinValue = -128
OnChange = seZChange
TabOrder = 2 TabOrder = 2
end end
end end

View File

@ -41,6 +41,7 @@ type
cbShowLayer: TCheckBox; cbShowLayer: TCheckBox;
seZ: TSpinEdit; seZ: TSpinEdit;
tbZ: TTrackBar; tbZ: TTrackBar;
procedure cbShowLayerChange(Sender: TObject);
procedure seZChange(Sender: TObject); procedure seZChange(Sender: TObject);
procedure tbZChange(Sender: TObject); procedure tbZChange(Sender: TObject);
public public
@ -52,16 +53,26 @@ var
implementation implementation
uses
UfrmMain;
{ TfrmVirtualLayer } { TfrmVirtualLayer }
procedure TfrmVirtualLayer.seZChange(Sender: TObject); procedure TfrmVirtualLayer.seZChange(Sender: TObject);
begin begin
tbZ.Position := seZ.Value; tbZ.Position := seZ.Value;
frmMain.InvalidateScreenBuffer;
end;
procedure TfrmVirtualLayer.cbShowLayerChange(Sender: TObject);
begin
frmMain.InvalidateScreenBuffer;
end; end;
procedure TfrmVirtualLayer.tbZChange(Sender: TObject); procedure TfrmVirtualLayer.tbZChange(Sender: TObject);
begin begin
seZ.Value := tbZ.Position; seZ.Value := tbZ.Position;
frmMain.InvalidateScreenBuffer;
end; end;
initialization initialization

View File

@ -179,7 +179,7 @@ type
{ Methods } { Methods }
procedure FillDrawList(ADrawList: TScreenBuffer; AX, AY, AWidth, procedure FillDrawList(ADrawList: TScreenBuffer; AX, AY, AWidth,
AHeight: Word; AMinZ, AMaxZ: ShortInt; AMap, AStatics: Boolean; AHeight: Word; AMinZ, AMaxZ: ShortInt; AMap, AStatics: Boolean;
ANoDraw: Boolean); ANoDraw: Boolean; AAdditionalTiles: TList = nil);
function GetEffectiveAltitude(ATile: TMapCell): ShortInt; function GetEffectiveAltitude(ATile: TMapCell): ShortInt;
function GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt; function GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt;
procedure GetNormals(AX, AY: Word; var ANormals: TNormals); procedure GetNormals(AX, AY: Word; var ANormals: TNormals);
@ -844,7 +844,7 @@ end;
procedure TLandscape.FillDrawList(ADrawList: TScreenBuffer; AX, AY, AWidth, procedure TLandscape.FillDrawList(ADrawList: TScreenBuffer; AX, AY, AWidth,
AHeight: Word; AMinZ, AMaxZ: ShortInt; AMap, AStatics: Boolean; AHeight: Word; AMinZ, AMaxZ: ShortInt; AMap, AStatics: Boolean;
ANoDraw: Boolean); ANoDraw: Boolean; AAdditionalTiles: TList = nil);
var var
landAlt: ShortInt; landAlt: ShortInt;
drawMapCell: TMapCell; drawMapCell: TMapCell;
@ -891,6 +891,9 @@ begin
end; end;
end; end;
if AAdditionalTiles <> nil then
tempDrawList.AddList(AAdditionalTiles);
tempDrawList.Sort(@CompareWorldItems); tempDrawList.Sort(@CompareWorldItems);
for i := 0 to tempDrawList.Count - 1 do for i := 0 to tempDrawList.Count - 1 do
ADrawList.Add(TWorldItem(tempDrawList[i])); ADrawList.Add(TWorldItem(tempDrawList[i]));

View File

@ -34,12 +34,11 @@ uses
ComCtrls, OpenGLContext, GL, GLU, UGameResources, ULandscape, ExtCtrls, ComCtrls, OpenGLContext, GL, GLU, UGameResources, ULandscape, ExtCtrls,
StdCtrls, Spin, UEnums, VirtualTrees, Buttons, UMulBlock, UWorldItem, math, StdCtrls, Spin, UEnums, VirtualTrees, Buttons, UMulBlock, UWorldItem, math,
LCLIntf, UOverlayUI, UStatics, UEnhancedMemoryStream, ActnList, LCLIntf, UOverlayUI, UStatics, UEnhancedMemoryStream, ActnList,
ImagingClasses, dateutils, UPlatformTypes, UVector, UMap; ImagingClasses, dateutils, UPlatformTypes, UVector, UMap, contnrs;
type type
TVirtualTile = class(TStaticItem); TVirtualTile = class(TStaticItem);
TVirtualTileArray = array of TVirtualTile;
TAccessChangedListener = procedure(AAccessLevel: TAccessLevel) of object; TAccessChangedListener = procedure(AAccessLevel: TAccessLevel) of object;
TScreenBufferState = (sbsValid, sbsIndexed, sbsFiltered); TScreenBufferState = (sbsValid, sbsIndexed, sbsFiltered);
@ -282,7 +281,7 @@ type
FCurrentTile: TWorldItem; FCurrentTile: TWorldItem;
FSelectedTile: TWorldItem; FSelectedTile: TWorldItem;
FGhostTile: TWorldItem; FGhostTile: TWorldItem;
FVirtualLayer: array of TVirtualTileArray; FVirtualTiles: TObjectList;
FVLayerMaterial: TMaterial; FVLayerMaterial: TMaterial;
FOverlayUI: TOverlayUI; FOverlayUI: TOverlayUI;
FLocationsFile: string; FLocationsFile: string;
@ -298,9 +297,7 @@ type
function GetSelectedRect: TRect; function GetSelectedRect: TRect;
procedure InitRender; procedure InitRender;
procedure InitSize; procedure InitSize;
procedure InvalidateScreenBuffer;
procedure PrepareScreenBlock(ABlockInfo: PBlockInfo); procedure PrepareScreenBlock(ABlockInfo: PBlockInfo);
procedure PrepareVirtualLayer(AWidth, AHeight: Word);
procedure ProcessToolState; procedure ProcessToolState;
procedure ProcessAccessLevel; procedure ProcessAccessLevel;
procedure RebuildScreenBuffer; procedure RebuildScreenBuffer;
@ -335,6 +332,7 @@ type
property SelectedTile: TWorldItem read FSelectedTile write SetSelectedTile; property SelectedTile: TWorldItem read FSelectedTile write SetSelectedTile;
{ Methods } { Methods }
procedure InvalidateFilter; procedure InvalidateFilter;
procedure InvalidateScreenBuffer;
procedure RegisterAccessChangedListener(AListener: TAccessChangedListener); procedure RegisterAccessChangedListener(AListener: TAccessChangedListener);
procedure SetPos(AX, AY: Word); procedure SetPos(AX, AY: Word);
procedure UnregisterAccessChangedListener(AListener: TAccessChangedListener); procedure UnregisterAccessChangedListener(AListener: TAccessChangedListener);
@ -769,6 +767,8 @@ begin
FVLayerMaterial := TMaterial.Create(virtualLayerGraphic.Width, virtualLayerGraphic.Height, FVLayerMaterial := TMaterial.Create(virtualLayerGraphic.Width, virtualLayerGraphic.Height,
virtualLayerGraphic); virtualLayerGraphic);
virtualLayerGraphic.Free; virtualLayerGraphic.Free;
FVirtualTiles := TObjectList.Create(True);
FRandomPresetLocation := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)) + 'RandomPresets' + PathDelim; FRandomPresetLocation := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)) + 'RandomPresets' + PathDelim;
if not DirectoryExists(FRandomPresetLocation) then CreateDir(FRandomPresetLocation); if not DirectoryExists(FRandomPresetLocation) then CreateDir(FRandomPresetLocation);
@ -1030,12 +1030,12 @@ begin
vstLocations.SaveToFile(FLocationsFile); vstLocations.SaveToFile(FLocationsFile);
if FTextureManager <> nil then FreeAndNil(FTextureManager); FreeAndNil(FTextureManager);
if FScreenBuffer <> nil then FreeAndNil(FScreenBuffer); FreeAndNil(FScreenBuffer);
if FOverlayUI <> nil then FreeAndNil(FOverlayUI); FreeAndNil(FOverlayUI);
if FGhostTile <> nil then FreeAndNil(FGhostTile); FreeAndNil(FGhostTile);
if FVLayerMaterial <> nil then FreeAndNil(FVLayerMaterial); FreeAndNil(FVLayerMaterial);
PrepareVirtualLayer(0, 0); //Clear FreeAndNil(FVirtualTiles);
RegisterPacketHandler($0C, nil); RegisterPacketHandler($0C, nil);
end; end;
@ -1742,6 +1742,19 @@ begin
ABlockInfo^.DrawQuad[3][1] := drawY + ABlockInfo^.LowRes.Height - z * 4; ABlockInfo^.DrawQuad[3][1] := drawY + ABlockInfo^.LowRes.Height - z * 4;
end; end;
end else end else
if item is TVirtualTile then
begin
ABlockInfo^.LowRes := FVLayerMaterial;
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44);
ABlockInfo^.DrawQuad[0][0] := drawX - 22;
ABlockInfo^.DrawQuad[0][1] := drawY - z * 4;
ABlockInfo^.DrawQuad[1][0] := drawX - 22 + ABlockInfo^.LowRes.Width;
ABlockInfo^.DrawQuad[1][1] := drawY - z * 4;
ABlockInfo^.DrawQuad[2][0] := drawX - 22 + ABlockInfo^.LowRes.Width;
ABlockInfo^.DrawQuad[2][1] := drawY + ABlockInfo^.LowRes.Height - z * 4;
ABlockInfo^.DrawQuad[3][0] := drawX - 22;
ABlockInfo^.DrawQuad[3][1] := drawY + ABlockInfo^.LowRes.Height - z * 4;
end else
begin begin
staticItem := TStaticItem(item); staticItem := TStaticItem(item);
@ -1799,11 +1812,6 @@ begin
if not (sbsFiltered in FScreenBufferState) then if not (sbsFiltered in FScreenBufferState) then
UpdateFilter; UpdateFilter;
{if acFilter.Checked then
staticsFilter := @frmFilter.Filter
else
staticsFilter := nil;} //TODO : update list on change}
blockInfo := nil; blockInfo := nil;
while FScreenBuffer.Iterate(blockInfo) do while FScreenBuffer.Iterate(blockInfo) do
@ -1813,7 +1821,7 @@ begin
item := blockInfo^.Item; item := blockInfo^.Item;
if acSelect.Checked or item.CanBeEdited then if acSelect.Checked or item.CanBeEdited or (item is TVirtualTile) then
begin begin
intensity := 1.0; intensity := 1.0;
SetNormalLights; SetNormalLights;
@ -2247,8 +2255,13 @@ end;
procedure TfrmMain.RebuildScreenBuffer; procedure TfrmMain.RebuildScreenBuffer;
var var
blockInfo: PBlockInfo; blockInfo: PBlockInfo;
i, tileX, tileY: Integer;
virtualTile: TVirtualTile;
begin begin
Logger.EnterMethod([lcClient], 'RebuildScreenBuffer');
FDrawDistance := Trunc(Sqrt(oglGameWindow.Width * oglGameWindow.Width + oglGamewindow.Height * oglGamewindow.Height) / 44); FDrawDistance := Trunc(Sqrt(oglGameWindow.Width * oglGameWindow.Width + oglGamewindow.Height * oglGamewindow.Height) / 44);
Logger.Send([lcClient], 'DrawDistance', FDrawDistance);
{$HINTS off}{$WARNINGS off} {$HINTS off}{$WARNINGS off}
if FX - FDrawDistance < 0 then FLowOffsetX := -FX else FLowOffsetX := -FDrawDistance; if FX - FDrawDistance < 0 then FLowOffsetX := -FX else FLowOffsetX := -FDrawDistance;
@ -2261,14 +2274,54 @@ begin
FRangeY := FHighOffsetY - FLowOffsetY; FRangeY := FHighOffsetY - FLowOffsetY;
FLandscape.PrepareBlocks((FX + FLowOffsetX) div 8, (FY + FLowOffsetY) div 8, (FX + FHighOffsetX) div 8 + 1, (FY + FHighOffsetY) div 8 + 1); FLandscape.PrepareBlocks((FX + FLowOffsetX) div 8, (FY + FLowOffsetY) div 8, (FX + FHighOffsetX) div 8 + 1, (FY + FHighOffsetY) div 8 + 1);
PrepareVirtualLayer(FDrawDistance * 2 + 1, FDrawDistance * 2 + 1);
//FScreenBuffer.Clear; if frmVirtualLayer.cbShowLayer.Checked then
//TODO : Virtual Layer begin
Logger.Send([lcClient, lcDebug], 'Preparing Virtual Layer');
i := 0;
for tileX := FX + FLowOffsetX to FX + FHighOffsetX do
begin
for tileY := FY + FLowOffsetY to FY + FHighOffsetY do
begin
while (i < FVirtualTiles.Count) and (not (FVirtualTiles[i] is TVirtualTile)) do
Inc(i);
if i < FVirtualTiles.Count then
begin
virtualTile := TVirtualTile(FVirtualTiles[i]);
end else
begin
virtualTile := TVirtualTile.Create(nil, nil, 0, 0);
FVirtualTiles.Add(virtualTile);
end;
virtualTile.X := tileX;
virtualTile.Y := tileY;
virtualTile.Z := frmVirtualLayer.seZ.Value;
Inc(i);
end;
end;
while i < FVirtualTiles.Count do
begin
if FVirtualTiles[i] is TVirtualTile then
FVirtualTiles.Delete(i)
else
Inc(i);
end;
end else
begin
for i := FVirtualTiles.Count - 1 downto 0 do
if FVirtualTiles[i] is TVirtualTile then
FVirtualTiles.Delete(i);
end;
Logger.Send([lcClient, lcDebug], 'VirtualTiles', FVirtualTiles.Count);
FLandscape.FillDrawList(FScreenBuffer, FX + FLowOffsetX, FY + FLowOffsetY, FLandscape.FillDrawList(FScreenBuffer, FX + FLowOffsetX, FY + FLowOffsetY,
FRangeX, FRangeY, frmBoundaries.tbMinZ.Position, FRangeX, FRangeY, frmBoundaries.tbMinZ.Position,
frmBoundaries.tbMaxZ.Position, tbTerrain.Down, tbStatics.Down, frmBoundaries.tbMaxZ.Position, tbTerrain.Down, tbStatics.Down,
acNoDraw.Checked); //TODO : statics filter acNoDraw.Checked, FVirtualTiles);
//TODO : ghost tile //TODO : ghost tile
//Pre-process the buffer //Pre-process the buffer
@ -2278,6 +2331,8 @@ begin
FScreenBuffer.UpdateShortcuts; FScreenBuffer.UpdateShortcuts;
FScreenBufferState := [sbsValid, sbsIndexed]; FScreenBufferState := [sbsValid, sbsIndexed];
Logger.ExitMethod([lcClient], 'RebuildScreenBuffer');
end; end;
procedure TfrmMain.UpdateCurrentTile; procedure TfrmMain.UpdateCurrentTile;
@ -2414,56 +2469,6 @@ begin
end; end;
end; end;
procedure TfrmMain.PrepareVirtualLayer(AWidth, AHeight: Word);
var
oldWidth, oldHeight: Word;
i, j: Integer;
begin
for i := Low(FVirtualLayer) to High(FVirtualLayer) do
begin
if AHeight < Length(FVirtualLayer[i]) then
begin
for j := AHeight to Length(FVirtualLayer[i]) - 1 do
FVirtualLayer[i][j].Free;
SetLength(FVirtualLayer[i], AHeight);
end else if AHeight > Length(FVirtualLayer[i]) then
begin
oldHeight := Length(FVirtualLayer[i]);
SetLength(FVirtualLayer[i], AHeight);
for j := oldHeight to AHeight - 1 do
begin
FVirtualLayer[i][j] := TVirtualTile.Create(nil, nil, 0, 0);
FVirtualLayer[i][j].TileID := 0;
FVirtualLayer[i][j].Hue := 0;
end;
end;
end;
if AWidth < Length(FVirtualLayer) then
begin
for i := AWidth to Length(FVirtualLayer) - 1 do
begin
for j := Low(FVirtualLayer[i]) to High(FVirtualLayer[i]) do
FVirtualLayer[i][j].Free;
end;
SetLength(FVirtualLayer, AWidth);
end else if AWidth > Length(FVirtualLayer) then
begin
oldWidth := Length(FVirtualLayer);
SetLength(FVirtualLayer, AWidth);
for i := oldWidth to AWidth - 1 do
begin
SetLength(FVirtualLayer[i], AHeight);
for j := Low(FVirtualLayer[i]) to High(FVirtualLayer[i]) do
begin
FVirtualLayer[i][j] := TVirtualTile.Create(nil, nil, 0, 0);
FVirtualLayer[i][j].TileID := 0;
FVirtualLayer[i][j].Hue := 0;
end;
end;
end;
end;
procedure TfrmMain.OnClientHandlingPacket(ABuffer: TEnhancedMemoryStream); procedure TfrmMain.OnClientHandlingPacket(ABuffer: TEnhancedMemoryStream);
var var
sender, msg: string; sender, msg: string;