# HG changeset patch # User nemo # Date 1338763942 14400 # Node ID 84ac6c6d2d8e3fa7a3dcb130c27d5b9f4de4edf2 # Parent 8defaabce92e7006c57c82b7ab6de250393a3eb8 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 diff -r 8defaabce92e -r 84ac6c6d2d8e hedgewars/GSHandlers.inc --- 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 //////////////////////////////////// diff -r 8defaabce92e -r 84ac6c6d2d8e hedgewars/uLand.pas --- 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); diff -r 8defaabce92e -r 84ac6c6d2d8e hedgewars/uLandGraphics.pas --- 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; diff -r 8defaabce92e -r 84ac6c6d2d8e hedgewars/uLandTexture.pas --- 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; diff -r 8defaabce92e -r 84ac6c6d2d8e hedgewars/uStore.pas --- 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;