- Changed several OpenGL calls with their integer-equivalents (we don't use floats anyway)
- Added a "real quad" to the screenbuffer to keep track of the original terrain locations - Added OpenGL based hit test to TScreenBuffer.Find
This commit is contained in:
parent
082770f183
commit
14ab47bdf8
|
@ -201,7 +201,8 @@ type
|
||||||
PBlockInfo = ^TBlockInfo;
|
PBlockInfo = ^TBlockInfo;
|
||||||
TBlockInfo = record
|
TBlockInfo = record
|
||||||
ScreenRect: TRect;
|
ScreenRect: TRect;
|
||||||
DrawQuad: array[0..3,0..1] of TGLfloat;
|
DrawQuad: array[0..3,0..1] of TGLint;
|
||||||
|
RealQuad: array[0..3,0..1] of TGLint;
|
||||||
Item: TWorldItem;
|
Item: TWorldItem;
|
||||||
HighRes: TMaterial;
|
HighRes: TMaterial;
|
||||||
LowRes: TMaterial;
|
LowRes: TMaterial;
|
||||||
|
@ -209,6 +210,7 @@ type
|
||||||
State: TScreenState;
|
State: TScreenState;
|
||||||
Highlighted: Boolean;
|
Highlighted: Boolean;
|
||||||
HueOverride: Boolean;
|
HueOverride: Boolean;
|
||||||
|
CheckRealQuad: Boolean;
|
||||||
Next: PBlockInfo;
|
Next: PBlockInfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1278,17 +1280,51 @@ end;
|
||||||
function TScreenBuffer.Find(AScreenPosition: TPoint): PBlockInfo;
|
function TScreenBuffer.Find(AScreenPosition: TPoint): PBlockInfo;
|
||||||
var
|
var
|
||||||
current: PBlockInfo;
|
current: PBlockInfo;
|
||||||
|
buff: array[0..3] of GLuint;
|
||||||
|
hits: GLint;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
current := FShortCuts[0];
|
current := FShortCuts[0];
|
||||||
while current <> nil do //search the last matching tile
|
while current <> nil do //search the last matching tile
|
||||||
begin
|
begin
|
||||||
if (current^.State = ssNormal) and
|
if (current^.State = ssNormal) and
|
||||||
PtInRect(current^.ScreenRect, AScreenPosition) and
|
PtInRect(current^.ScreenRect, AScreenPosition)then
|
||||||
current^.LowRes.HitTest(AScreenPosition.x - current^.ScreenRect.Left,
|
|
||||||
AScreenPosition.y - current^.ScreenRect.Top) then
|
|
||||||
begin
|
begin
|
||||||
Result := current;
|
if current^.CheckRealQuad then
|
||||||
|
begin
|
||||||
|
//OpenGL hit test
|
||||||
|
//We use the "real quad" here to prevent the draw-preview from
|
||||||
|
//intercepting with our actual tiles (which are "hidden" then).
|
||||||
|
glSelectBuffer(4, @buff[0]);
|
||||||
|
glViewport(current^.ScreenRect.Left, current^.ScreenRect.Top,
|
||||||
|
current^.ScreenRect.Right, current^.ScreenRect.Bottom);
|
||||||
|
glRenderMode(GL_SELECT);
|
||||||
|
glInitNames;
|
||||||
|
glPushName(0);
|
||||||
|
|
||||||
|
glPushMatrix;
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity;
|
||||||
|
gluOrtho2D(AScreenPosition.x, AScreenPosition.x + 1,
|
||||||
|
AScreenPosition.y + 1, AScreenPosition.y);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity;
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2iv(@current^.RealQuad[0]);
|
||||||
|
glVertex2iv(@current^.RealQuad[3]);
|
||||||
|
glVertex2iv(@current^.RealQuad[2]);
|
||||||
|
glVertex2iv(@current^.RealQuad[1]);
|
||||||
|
glEnd;
|
||||||
|
glPopMatrix;
|
||||||
|
glFlush;
|
||||||
|
|
||||||
|
if glRenderMode(GL_RENDER) > 0 then //glRenderMode now returns the number of hits
|
||||||
|
Result := current;
|
||||||
|
end else
|
||||||
|
if current^.LowRes.HitTest(AScreenPosition.x - current^.ScreenRect.Left,
|
||||||
|
AScreenPosition.y - current^.ScreenRect.Top) then
|
||||||
|
Result := current;
|
||||||
end;
|
end;
|
||||||
current := current^.Next;
|
current := current^.Next;
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -292,7 +292,7 @@ type
|
||||||
procedure BuildTileList;
|
procedure BuildTileList;
|
||||||
function ConfirmAction: Boolean;
|
function ConfirmAction: Boolean;
|
||||||
procedure GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX,
|
procedure GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX,
|
||||||
DrawY: Single); inline;
|
DrawY: Integer); inline;
|
||||||
function GetInternalTileID(ATile: TWorldItem): Word;
|
function GetInternalTileID(ATile: TWorldItem): Word;
|
||||||
function GetSelectedRect: TRect;
|
function GetSelectedRect: TRect;
|
||||||
procedure InitRender;
|
procedure InitRender;
|
||||||
|
@ -1687,7 +1687,7 @@ begin
|
||||||
glDisable(GL_DITHER);
|
glDisable(GL_DITHER);
|
||||||
glEnable(GL_BLEND); // Enable alpha blending of textures
|
glEnable(GL_BLEND); // Enable alpha blending of textures
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glShadeModel(GL_SMOOTH); // Go with flat shading for now
|
glShadeModel(GL_SMOOTH);
|
||||||
glEnable(GL_NORMALIZE);
|
glEnable(GL_NORMALIZE);
|
||||||
|
|
||||||
glEnable(GL_LIGHT0);
|
glEnable(GL_LIGHT0);
|
||||||
|
@ -1716,11 +1716,29 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TfrmMain.PrepareScreenBlock(ABlockInfo: PBlockInfo);
|
procedure TfrmMain.PrepareScreenBlock(ABlockInfo: PBlockInfo);
|
||||||
|
|
||||||
|
procedure GetLandAlt(const AX, AY: Integer; const ADefaultZ,
|
||||||
|
ADefaultRaw: SmallInt; var Z, RawZ: SmallInt);
|
||||||
|
var
|
||||||
|
cell: TMapCell;
|
||||||
|
begin
|
||||||
|
cell := FLandscape.MapCell[AX, AY];
|
||||||
|
if cell <> nil then
|
||||||
|
begin
|
||||||
|
Z := cell.Z;
|
||||||
|
RawZ := cell.RawZ;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
Z := ADefaultZ;
|
||||||
|
RawZ := ADefaultRaw;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
item: TWorldItem;
|
item: TWorldItem;
|
||||||
drawX, drawY: Single;
|
drawX, drawY: Integer;
|
||||||
west, south, east: Single;
|
z, west, south, east: SmallInt;
|
||||||
z, rawZ: SmallInt;
|
rawZ, rawWest, rawSouth, rawEast: SmallInt;
|
||||||
staticItem: TStaticItem;
|
staticItem: TStaticItem;
|
||||||
begin
|
begin
|
||||||
//add normals to map tiles and materials where possible
|
//add normals to map tiles and materials where possible
|
||||||
|
@ -1739,23 +1757,58 @@ begin
|
||||||
rawZ := item.RawZ;
|
rawZ := item.RawZ;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
ABlockInfo^.HighRes := nil;
|
||||||
|
ABlockInfo^.CheckRealQuad := False;
|
||||||
if item is TMapCell then
|
if item is TMapCell then
|
||||||
begin
|
begin
|
||||||
ABlockInfo^.HighRes := nil;
|
|
||||||
if not acFlat.Checked then
|
if not acFlat.Checked then
|
||||||
begin
|
begin
|
||||||
west := FLandscape.GetLandAlt(item.X, item.Y + 1, z);
|
GetLandAlt(item.X, item.Y + 1, z, rawZ, west, rawWest);
|
||||||
south := FLandscape.GetLandAlt(item.X + 1, item.Y + 1, z);
|
GetLandAlt(item.X + 1, item.Y + 1, z, rawZ, south, rawSouth);
|
||||||
east := FLandscape.GetLandAlt(item.X + 1, item.Y, z);
|
GetLandAlt(item.X + 1, item.Y, z, rawZ, east, rawEast);
|
||||||
|
|
||||||
if (west <> z) or (south <> z) or (east <> z) then
|
if (west <> z) or (south <> z) or (east <> z) then
|
||||||
begin
|
|
||||||
ABlockInfo^.HighRes := FTextureManager.GetTexMaterial(item.TileID);
|
ABlockInfo^.HighRes := FTextureManager.GetTexMaterial(item.TileID);
|
||||||
|
|
||||||
|
if (rawWest <> rawZ) or (rawSouth <> rawZ) or (rawEast <> rawZ) then
|
||||||
|
begin
|
||||||
|
ABlockInfo^.RealQuad[0][0] := drawX;
|
||||||
|
ABlockInfo^.RealQuad[0][1] := drawY - rawZ * 4;
|
||||||
|
ABlockInfo^.RealQuad[1][0] := drawX + 22;
|
||||||
|
ABlockInfo^.RealQuad[1][1] := drawY + 22 - rawEast * 4;
|
||||||
|
ABlockInfo^.RealQuad[2][0] := drawX;
|
||||||
|
ABlockInfo^.RealQuad[2][1] := drawY + 44 - rawSouth * 4;
|
||||||
|
ABlockInfo^.RealQuad[3][0] := drawX - 22;
|
||||||
|
ABlockInfo^.RealQuad[3][1] := drawY + 22 - rawWest * 4;
|
||||||
|
|
||||||
|
with ABlockInfo^ do
|
||||||
|
begin
|
||||||
|
with ScreenRect do
|
||||||
|
begin
|
||||||
|
Left := drawX - 22;
|
||||||
|
Right := drawX + 22;
|
||||||
|
Top := RealQuad[0][1];
|
||||||
|
Bottom := RealQuad[0][1];
|
||||||
|
|
||||||
|
if RealQuad[1][1] < Top then Top := RealQuad[1][1];
|
||||||
|
if RealQuad[1][1] > Bottom then Bottom := RealQuad[1][1];
|
||||||
|
|
||||||
|
if RealQuad[2][1] < Top then Top := RealQuad[2][1];
|
||||||
|
if RealQuad[2][1] > Bottom then Bottom := RealQuad[2][1];
|
||||||
|
|
||||||
|
if RealQuad[3][1] < Top then Top := RealQuad[3][1];
|
||||||
|
if RealQuad[3][1] > Bottom then Bottom := RealQuad[3][1];
|
||||||
|
end;
|
||||||
|
CheckRealQuad := True;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if not ABlockInfo^.CheckRealQuad then
|
||||||
|
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22),
|
||||||
|
Trunc(drawY - rawZ * 4), 44, 44);
|
||||||
|
|
||||||
ABlockInfo^.LowRes := FTextureManager.GetArtMaterial(item.TileID);
|
ABlockInfo^.LowRes := FTextureManager.GetArtMaterial(item.TileID);
|
||||||
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - rawZ * 4), 44, 44);
|
|
||||||
|
|
||||||
if ABlockInfo^.HighRes <> nil then
|
if ABlockInfo^.HighRes <> nil then
|
||||||
begin
|
begin
|
||||||
|
@ -1785,7 +1838,8 @@ begin
|
||||||
if item is TVirtualTile then
|
if item is TVirtualTile then
|
||||||
begin
|
begin
|
||||||
ABlockInfo^.LowRes := FVLayerMaterial;
|
ABlockInfo^.LowRes := FVLayerMaterial;
|
||||||
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44);
|
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4),
|
||||||
|
44, 44);
|
||||||
ABlockInfo^.DrawQuad[0][0] := drawX - 22;
|
ABlockInfo^.DrawQuad[0][0] := drawX - 22;
|
||||||
ABlockInfo^.DrawQuad[0][1] := drawY - z * 4;
|
ABlockInfo^.DrawQuad[0][1] := drawY - z * 4;
|
||||||
ABlockInfo^.DrawQuad[1][0] := drawX - 22 + ABlockInfo^.LowRes.Width;
|
ABlockInfo^.DrawQuad[1][0] := drawX - 22 + ABlockInfo^.LowRes.Width;
|
||||||
|
@ -1866,46 +1920,36 @@ begin
|
||||||
glLogicOp(GL_COPY_INVERTED);
|
glLogicOp(GL_COPY_INVERTED);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if item is TMapCell then
|
if blockInfo^.HighRes <> nil then
|
||||||
begin
|
begin
|
||||||
if blockInfo^.HighRes <> nil then
|
glBindTexture(GL_TEXTURE_2D, blockInfo^.HighRes.Texture);
|
||||||
begin
|
|
||||||
glBindTexture(GL_TEXTURE_2D, blockInfo^.HighRes.Texture);
|
|
||||||
|
|
||||||
if not highlight then
|
if not highlight then
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glLoadName(PtrInt(item));
|
||||||
glNormal3fv(@blockInfo^.Normals^[0]);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(0, 0); glVertex2fv(@blockInfo^.DrawQuad[0]);
|
glNormal3fv(@blockInfo^.Normals^[0]);
|
||||||
glNormal3fv(@blockInfo^.Normals^[3]);
|
glTexCoord2i(0, 0); glVertex2iv(@blockInfo^.DrawQuad[0]);
|
||||||
glTexCoord2f(0, 1); glVertex2fv(@blockInfo^.DrawQuad[3]);
|
glNormal3fv(@blockInfo^.Normals^[3]);
|
||||||
glNormal3fv(@blockInfo^.Normals^[2]);
|
glTexCoord2i(0, 1); glVertex2iv(@blockInfo^.DrawQuad[3]);
|
||||||
glTexCoord2f(1, 1); glVertex2fv(@blockInfo^.DrawQuad[2]);
|
glNormal3fv(@blockInfo^.Normals^[2]);
|
||||||
glNormal3fv(@blockInfo^.Normals^[1]);
|
glTexCoord2i(1, 1); glVertex2iv(@blockInfo^.DrawQuad[2]);
|
||||||
glTexCoord2f(1, 0); glVertex2fv(@blockInfo^.DrawQuad[1]);
|
glNormal3fv(@blockInfo^.Normals^[1]);
|
||||||
glEnd;
|
glTexCoord2i(1, 0); glVertex2iv(@blockInfo^.DrawQuad[1]);
|
||||||
|
glEnd;
|
||||||
|
|
||||||
if not highlight then
|
if not highlight then
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
end else
|
|
||||||
begin
|
|
||||||
glBindTexture(GL_TEXTURE_2D, blockInfo^.LowRes.Texture);
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glTexCoord2f(0, 0); glVertex2fv(@blockInfo^.DrawQuad[0]);
|
|
||||||
glTexCoord2f(1, 0); glVertex2fv(@blockInfo^.DrawQuad[1]);
|
|
||||||
glTexCoord2f(1, 1); glVertex2fv(@blockInfo^.DrawQuad[2]);
|
|
||||||
glTexCoord2f(0, 1); glVertex2fv(@blockInfo^.DrawQuad[3]);
|
|
||||||
glEnd;
|
|
||||||
end;
|
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
glBindTexture(GL_TEXTURE_2D, blockInfo^.LowRes.Texture);
|
glBindTexture(GL_TEXTURE_2D, blockInfo^.LowRes.Texture);
|
||||||
|
glLoadName(PtrInt(item));
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(0, 0); glVertex2fv(@blockInfo^.DrawQuad[0]);
|
glTexCoord2i(0, 0); glVertex2iv(@blockInfo^.DrawQuad[0]);
|
||||||
glTexCoord2f(1, 0); glVertex2fv(@blockInfo^.DrawQuad[1]);
|
glTexCoord2i(1, 0); glVertex2iv(@blockInfo^.DrawQuad[1]);
|
||||||
glTexCoord2f(1, 1); glVertex2fv(@blockInfo^.DrawQuad[2]);
|
glTexCoord2i(1, 1); glVertex2iv(@blockInfo^.DrawQuad[2]);
|
||||||
glTexCoord2f(0, 1); glVertex2fv(@blockInfo^.DrawQuad[3]);
|
glTexCoord2i(0, 1); glVertex2iv(@blockInfo^.DrawQuad[3]);
|
||||||
glEnd;
|
glEnd;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -2193,7 +2237,7 @@ end;
|
||||||
|
|
||||||
procedure TfrmMain.UpdateCurrentTile(AX, AY: Integer);
|
procedure TfrmMain.UpdateCurrentTile(AX, AY: Integer);
|
||||||
var
|
var
|
||||||
info: PBlockInfo;
|
blockInfo: PBlockInfo;
|
||||||
begin
|
begin
|
||||||
FOverlayUI.ActiveArrow := FOverlayUI.HitTest(AX, AY);
|
FOverlayUI.ActiveArrow := FOverlayUI.HitTest(AX, AY);
|
||||||
if FOverlayUI.ActiveArrow > -1 then
|
if FOverlayUI.ActiveArrow > -1 then
|
||||||
|
@ -2202,11 +2246,10 @@ begin
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
info := FScreenBuffer.Find(Point(AX, AY));
|
blockInfo := FScreenBuffer.Find(Point(AX, AY));
|
||||||
if info <> nil then
|
if blockInfo <> nil then
|
||||||
begin
|
CurrentTile := blockInfo^.Item
|
||||||
CurrentTile := info^.Item;
|
else
|
||||||
end else
|
|
||||||
CurrentTile := nil;
|
CurrentTile := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -2547,7 +2590,7 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TfrmMain.GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX,
|
procedure TfrmMain.GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX,
|
||||||
DrawY: Single); inline;
|
DrawY: Integer); inline;
|
||||||
begin
|
begin
|
||||||
DrawX := (oglGameWindow.Width div 2) + (ARelativeX - ARelativeY) * 22;
|
DrawX := (oglGameWindow.Width div 2) + (ARelativeX - ARelativeY) * 22;
|
||||||
DrawY := (oglGamewindow.Height div 2) + (ARelativeX + ARelativeY) * 22;
|
DrawY := (oglGamewindow.Height div 2) + (ARelativeX + ARelativeY) * 22;
|
||||||
|
|
Loading…
Reference in New Issue