Only create textures for non-empty LandPixel chunks. This should save a fair amount of memory, especially on smaller maps, and eliminate a number of draws
--- a/hedgewars/GSHandlers.inc Sun Jun 03 11:02:12 2012 -0400
+++ b/hedgewars/GSHandlers.inc Sun Jun 03 18:52:22 2012 -0400
@@ -702,14 +702,14 @@
//Land[py, px+1]:= lfBasic;
if allpx then
- UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w))
+ UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
else
begin
UpdateLandTexture(
max(0, min(LAND_WIDTH, xx)),
min(LAND_WIDTH - xx, Pred(s^.w)),
max(0, min(LAND_WIDTH, yy)),
- min(LAND_HEIGHT - yy, Pred(s^.h))
+ min(LAND_HEIGHT - yy, Pred(s^.h)), false // could this be true without unnecessarily creating blanks?
);
end;
////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
--- a/hedgewars/uLand.pas Sun Jun 03 11:02:12 2012 -0400
+++ b/hedgewars/uLand.pas Sun Jun 03 18:52:22 2012 -0400
@@ -674,7 +674,7 @@
end
end;
-UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT);
+UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false);
end;
procedure GenPreview(out Preview: TPreview);
--- a/hedgewars/uLandGraphics.pas Sun Jun 03 11:02:12 2012 -0400
+++ b/hedgewars/uLandGraphics.pas Sun Jun 03 18:52:22 2012 -0400
@@ -463,7 +463,7 @@
dx:= Min(X + Radius + 1, LAND_WIDTH) - tx;
ty:= Max(Y - Radius - 1, 0);
dy:= Min(Y + Radius + 1, LAND_HEIGHT) - ty;
-UpdateLandTexture(tx, dx, ty, dy);
+UpdateLandTexture(tx, dx, ty, dy, false);
DrawExplosion:= cnt
end;
@@ -515,7 +515,7 @@
end;
-UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT)
+UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false)
end;
//
@@ -665,7 +665,7 @@
ddx:= Min(stX + HalfWidth * 2 + 4 + abs(hwRound(dX * ticks)), LAND_WIDTH) - tx;
ddy:= Min(stY + HalfWidth * 2 + 4 + abs(hwRound(dY * ticks)), LAND_HEIGHT) - ty;
-UpdateLandTexture(tx, ddx, ty, ddy)
+UpdateLandTexture(tx, ddx, ty, ddy, false)
end;
function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean;
@@ -753,7 +753,7 @@
w:= Min(cpX + Image^.w, LAND_WIDTH) - x;
y:= Max(cpY, topY);
h:= Min(cpY + Image^.h, LAND_HEIGHT) - y;
-UpdateLandTexture(x, w, y, h)
+UpdateLandTexture(x, w, y, h, true)
end;
function Despeckle(X, Y: LongInt): boolean;
@@ -955,7 +955,7 @@
end;
end;
if updateBlock then
- UpdateLandTexture(tx, 32, ty, 32);
+ UpdateLandTexture(tx, 32, ty, 32, false);
LandDirty[y, x]:= 2;
end;
end;
--- a/hedgewars/uLandTexture.pas Sun Jun 03 11:02:12 2012 -0400
+++ b/hedgewars/uLandTexture.pas Sun Jun 03 18:52:22 2012 -0400
@@ -24,17 +24,17 @@
procedure initModule;
procedure freeModule;
-procedure UpdateLandTexture(X, Width, Y, Height: LongInt);
+procedure UpdateLandTexture(X, Width, Y, Height: LongInt; landAdded: boolean);
procedure DrawLand(dX, dY: LongInt);
procedure ResetLand;
implementation
uses uConsts, GLunit, uTypes, uVariables, uTextures, uDebug, uRender;
-const TEXSIZE = 512;
+const TEXSIZE = 256;
type TLandRecord = record
- shouldUpdate: boolean;
+ shouldUpdate, landAdded: boolean;
tex: PTexture;
end;
@@ -62,7 +62,7 @@
Pixels2:= @tmpPixels
end;
-procedure UpdateLandTexture(X, Width, Y, Height: LongInt);
+procedure UpdateLandTexture(X, Width, Y, Height: LongInt; landAdded: boolean);
var tx, ty: Longword;
begin
if (Width <= 0) or (Height <= 0) then
@@ -75,16 +75,24 @@
if (cReducedQuality and rqBlurryLand) = 0 then
for ty:= Y div TEXSIZE to (Y + Height - 1) div TEXSIZE do
for tx:= X div TEXSIZE to (X + Width - 1) div TEXSIZE do
- LandTextures[tx, ty].shouldUpdate:= true
+ begin
+ LandTextures[tx, ty].shouldUpdate:= true;
+ LandTextures[tx, ty].landAdded:= landAdded
+ end
else
for ty:= (Y div TEXSIZE) div 2 to ((Y + Height - 1) div TEXSIZE) div 2 do
for tx:= (X div TEXSIZE) div 2 to ((X + Width - 1) div TEXSIZE) div 2 do
+ begin
LandTextures[tx, ty].shouldUpdate:= true;
+ LandTextures[tx, ty].landAdded:= landAdded
+ end
end;
procedure RealLandTexUpdate;
-var x, y: LongWord;
+var x, y, ty, tx, lx, ly : LongWord;
+ isEmpty: boolean;
begin
+(*
if LandTextures[0, 0].tex = nil then
for x:= 0 to LANDTEXARW -1 do
for y:= 0 to LANDTEXARH - 1 do
@@ -95,14 +103,67 @@
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, tpHigh);
end
else
+*)
for x:= 0 to LANDTEXARW -1 do
for y:= 0 to LANDTEXARH - 1 do
with LandTextures[x, y] do
if shouldUpdate then
begin
shouldUpdate:= false;
- glBindTexture(GL_TEXTURE_2D, tex^.id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXSIZE, TEXSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, Pixels(x,y));
+ isEmpty:= not landAdded;
+ landAdded:= false;
+ ty:= 0;
+ tx:= 1;
+ ly:= y * TEXSIZE;
+ lx:= x * TEXSIZE;
+ // first check edges
+ while isEmpty and (ty < TEXSIZE) do
+ begin
+ isEmpty:= LandPixels[ly + ty, lx] and AMask = 0;
+ if isEmpty then isEmpty:= LandPixels[ly + ty, lx + TEXSIZE-1] and AMask = 0;
+ inc(ty)
+ end;
+ while isEmpty and (tx < TEXSIZE-1) do
+ begin
+ isEmpty:= LandPixels[ly, lx + tx] and AMask = 0;
+ if isEmpty then isEmpty:= LandPixels[ly + TEXSIZE-1, lx + tx] and AMask = 0;
+ inc(tx)
+ end;
+ // then search every other remaining. does this sort of stuff defeat compiler opts?
+ ty:= 2;
+ while isEmpty and (ty < TEXSIZE-1) do
+ begin
+ tx:= 2;
+ while isEmpty and (tx < TEXSIZE-1) do
+ begin
+ isEmpty:= LandPixels[ly + ty, lx + tx] and AMask = 0;
+ inc(tx,2)
+ end;
+ inc(ty,2);
+ end;
+ // and repeat
+ ty:= 1;
+ while isEmpty and (ty < TEXSIZE-1) do
+ begin
+ tx:= 1;
+ while isEmpty and (tx < TEXSIZE-1) do
+ begin
+ isEmpty:= LandPixels[ly + ty, lx + tx] and AMask = 0;
+ inc(tx,2)
+ end;
+ inc(ty,2);
+ end;
+ if not isEmpty then
+ begin
+ if tex = nil then tex:= NewTexture(TEXSIZE, TEXSIZE, Pixels(x, y));
+ glBindTexture(GL_TEXTURE_2D, tex^.id);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXSIZE, TEXSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, Pixels(x,y));
+ end
+ else if tex <> nil then
+ begin
+ FreeTexture(tex);
+ tex:= nil
+ end;
end
end;
@@ -114,10 +175,11 @@
for x:= 0 to LANDTEXARW -1 do
for y:= 0 to LANDTEXARH - 1 do
with LandTextures[x, y] do
- if (cReducedQuality and rqBlurryLand) = 0 then
- DrawTexture(dX + x * TEXSIZE, dY + y * TEXSIZE, tex)
- else
- DrawTexture(dX + x * TEXSIZE * 2, dY + y * TEXSIZE * 2, tex, 2.0)
+ if tex <> nil then
+ if (cReducedQuality and rqBlurryLand) = 0 then
+ DrawTexture(dX + x * TEXSIZE, dY + y * TEXSIZE, tex)
+ else
+ DrawTexture(dX + x * TEXSIZE * 2, dY + y * TEXSIZE * 2, tex, 2.0)
end;
@@ -144,8 +206,11 @@
for y:= 0 to LANDTEXARH - 1 do
with LandTextures[x, y] do
begin
- FreeTexture(tex);
- tex:= nil;
+ if tex <> nil then
+ begin
+ FreeTexture(tex);
+ tex:= nil
+ end
end;
end;
--- a/hedgewars/uStore.pas Sun Jun 03 11:02:12 2012 -0400
+++ b/hedgewars/uStore.pas Sun Jun 03 18:52:22 2012 -0400
@@ -1118,7 +1118,7 @@
ReloadLines;
StoreLoad(true);
// redraw all land
- UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT);
+ UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false);
end;
end;